简体   繁体   中英

Why did language designers use angle brackets instead of parenthesis?

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?

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.

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.

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.

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.

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.

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM