4

Reading through the javase api docs, I noticed that pretty much all of the methods in the collections framework use angle brackets. For example:

Collection<String> c = new HashSet<String>();

or

Map<String, Integer> m = new HashMap<String, Integer>();

To the eye they seem to serve the same function as a set of parentheses. I still don't know enough of the Java language to be able to see an overarching connection where angle brackets are used and why that might be the case.

My question is specifically: Is there a significance to the way angle brackets are interpreted by the JVM as opposed to perens? Or is it just a common practice across multiple languages?

Steve the Maker
  • 611
  • 6
  • 11
  • 1
    If I remember right in `C++` -- where these were first introduced -- there was some parsing issue and any other symbol would have caused ambiguity. – Miserable Variable Mar 16 '12 at 20:45
  • You would have to ask the language designers, unless it is discussed in the specification. In this particular case the answer is fairly obvious, but in general questions like this are pretty pointless. – user207421 Mar 18 '12 at 22:17

7 Answers7

8

The angle brackets came with the introduction of generics in Java 1.5

Since this is a later addition to an existing language, I guess the angle brackets where chosen to make a clear distinction to the existing parentheses (method and constructor calls), square brackets (array member access) and curly brackets (block delimiters). I'd say angle brackets are the logical choice here.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • 4
    They were chosen because that's what C++ used :) – Miserable Variable Mar 16 '12 at 20:54
  • 1
    But I guess then my version still makes sense, only that it applies to C++, not Java :-) – Sean Patrick Floyd Mar 16 '12 at 21:01
  • Actually, IIRC, in C++ the () are an operator, that's not the case in Java. But the choice of using different delimiters makes the parser simpler. Using the same () for type arguments would mean there is an inherent ambiguity in the grammar, which can be avoided by using different symbols. – Jochen Mar 16 '12 at 22:49
  • @Jochen C++ grammar is already (or still, with angle bracktes for templates) ambiguous, see http://stackoverflow.com/a/243447/18573 which quotes "C++ grammar is ambiguous, context-dependent and potentially requires infinite lookahead to resolve some ambiguities" – Miserable Variable Mar 17 '12 at 21:34
  • I know that. Almost every modern language has some ambiguity in its grammar. But why add more when you don't have to? – Jochen Mar 17 '12 at 22:35
  • @Jochen: Actually, it makes the parser much, much more difficult. Now there is ambiguity in `A – Callum Rogers Apr 16 '13 at 17:15
3

Is there a significance to the way angle brackets are interpreted by the JVM as opposed to perens?

None of them is interpreted by the JVM [neither the braces, nor angle brackets], both parentheses and angle brackets are parsed during compile time, and the JVM doesn't see them, since the JVM is active on run time.

As side notes:

  1. The <> are used for generics, and their usage is also common in other languages such as C++.

  2. You are referring to new HashSet<String>(); as a method - it is not, it is invoking a constructor. A constructor is not a method.

Steve the Maker
  • 611
  • 6
  • 11
amit
  • 175,853
  • 27
  • 231
  • 333
  • `A constructor is not a method.` I'm not sure I agree with that. Constructors are a special kind of method. – Sean Patrick Floyd Mar 16 '12 at 21:00
  • @SeanPatrickFloyd: I think this point is ambigious, but the java specifications always refer to "method and constructor" when trying to say something for both, and not just "method", for example [Method and Constructor declaration](http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.12) – amit Mar 16 '12 at 21:19
  • @SeanPatrickFloyd: Still not conclusive but more informative: from [chapter 8 - classes](http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html): `Constructors (§8.8) are similar to methods, but cannot be invoked directly by a method call; they are used to initialize new class instances. Like methods, they may be overloaded (§8.8.8). `. **Though it still is not definitive** - it seems the specs point that constructors and methods have similarities - but constructors are not methods. – amit Mar 16 '12 at 21:25
3

Parentheses are already reserved for method calls and expression grouping. Angle brackets are used for generic type parameters.

If parentheses were used for both, things could become ambiguous, if not for the compiler, then at least for the reader.

tdammers
  • 20,353
  • 1
  • 39
  • 56
  • 1
    + 1 brevity. Did you mean _ambiguous_ ? – calebds Mar 16 '12 at 20:50
  • Seems to me it would make Java's grammar context sensitive, which certainly isn't something you want for your language (but then, the c++ guys have that problem and cope with it) – Voo Mar 16 '12 at 20:53
3

I guess they are used in Java because they are used in C++, just like everything from int to void.

Found some interesting references, though partial:

From C++ templates: the complete guide By David Vandevoorde, Nicolai M. Josuttis, page 139:

Relatively early during the development of templates, Tom Pennello—a widely recognized parsing expert working for Metaware—noted some of the problems associated with angle brackets. Stroustrup also comments on that topic in [DnE] and argues that humans prefer to read angle brackets rather than parentheses. However, other possibilities exist, and Pennello specifically proposed braces (for example. List{: :X}) at a C++ standards meeting in 1991 (held in Dallas) At that time the extent of the problem was more limited because templates nested inside other templates—so-called nested templates —were not valid and thus the discussion of Section 9.3.3 on page 132 was largely irrelevant. As a result. the committee declined the proposal to replace the angle brackets.

So I may have been mistaken that the angled brackets were used to help the parser, perhaps they were used to help the programmer, because Bjarne Stroustrup thought they were better.

Miserable Variable
  • 28,432
  • 15
  • 72
  • 133
0

In Java, angle brackets indicate the use of a generic type, which is a type that has different semantics depending on the type passed in.

The simplest use case for generics is in specialized collections, to indicate that they should hold only objects of a particular type.

In Java, generics do not actually add a lot to the language except basic enforcement functionality at run-time. Objects inserted into or retrieved from a collection are automatically cast to the given type at run time (risking a ClassCastException in the worst case). There is no compile-time checking for generic types in the language specification.

Platinum Azure
  • 45,269
  • 12
  • 110
  • 134
0

Angle brackets are used to denote type parameter lists for polymorphic ("generic") classes and methods. These are a very different beast from value parameter lists (the stuff in parentheses). If they were the same, then imagine you have the expression new Foo(bar)... How would the parser interpret this? Is bar the name of a type or the name of a variable?

mergeconflict
  • 8,156
  • 34
  • 63
-1

Imagine that C++ used () instead of <> for templates. Now consider this line of code:

foo(bar)*bang;

Is that:

  1. Declaring a local variable bang whose type is a pointer to the template type foo with type argument bar?
  2. Calling the function foo, passing in bar, then multiplying the result by bang?

It's grammatically ambiguous. We could tweak the grammar such that it would always prefer one over the other, but that makes the (already painfully complex) grammar even hairier. Worse, whichever way you pick, users will probably guess wrong sometimes.

So, for C++, it makes sense to use a different grouping character for templates.

Java then just followed in C++'s footsteps.

Most of the trouble here stem's from C's decision to not have explicit syntax for variable declaration and instead just use a type annotation to implicitly mean "make a new variable of that type". Languages like Scala which have explicit keywords (var and val) for variables have more freedom with type declaration syntax, which is why they can use [] for generics.

munificent
  • 11,946
  • 2
  • 38
  • 55