Why is it wrong to specify a type parameter in a constructor of a general class (Java)?

I just learn generalizations in Java from a tutorial where he talks about the GenericStack<E> class implemented with ArrayList<E> .

Since you use a line stack to create

 GenericStack<String> = new GenericStack<String>() 

or

 GenericStack<String> new GenericStack<>() 

therefore, should not the GenericStack constructor GenericStack defined as public GenericStack<E>() or public GenericStack<>() ? The answer is no. It must be defined as public GenericStack() .

Why is this? Obviously, a constructor can easily infer a type from a class declaration, but given the verbosity of Java, I'm a little puzzled why a formal <E> or just a formal <> completely freed from this.

+2
java syntax generics constructor oop
source share
3 answers

There are two parts:

  • The general type parameter specified to define the class is available within the class itself.

  • You may have generic types specific to particular methods (including constructor).

Take a look at the following example:

 package snippet; import java.util.ArrayList; public class Y<E> extends ArrayList<E> { public <T> Y(T t) { } } 

If type E is available for the entire class, type T valid only inside the constructor.

+7
source share

You are misleading to declare a method with its call site (that is, where you use it). If you want to use the generic class declared in the class, you only ever need to provide <E> or <> on the calling site - not the declaration. And in this regard, the constructor is declared like any other method:

 public GenericStack<E> { public E get() { ... // correct public <E> put(E element) { ... // bad (see below) public GenericStack() { ... // correct, like the get() 

Reusing the generic (as is the case with the put tag above) actually obscures it; E in put(E) is actually different from E than in GenericStack<E> , despite the same name. This is confusing and you should avoid this.

+1
source share

Both the class and the constructor can be shared on their own, that is, each has its own type parameters. for example

 class A<T> { <S>A(S s){} } 

To call a constructor with all explicit type arguments

 new <String>A<Integer>("abc"); // T=Integer, S=String 

Think of it this way: A<Integer> is a concrete class, and <String>A is a concrete constructor.

Due to type inference, we can omit the type argument for the constructor

 new A<Integer>("abc"); // S=String is inferred 

The type argument for the class can also be omitted and output using the syntax "diamond" ( <> )

 A<Integer> a = new A<>("abc"); // T=Integer is inferred, as well as S=String 

I wrote a (long) post on this subject - fooobar.com/questions/830135 / ...

+1
source share

All Articles