• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

generic class

 
Ranch Hand
Posts: 135
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I have a written a generic class like below:




My question is why there is a compilation error at "private T t = new T();" .. showing cannot instantiate type T

Thanks in Advance!
 
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'll leave it to someone more versed in generics to explain why the compiler can't handle that, but how about this as an alternative?

 
Stevens Miller
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Further to the above, your question is partially addressed in one of the Java Tutorials. A (more complex?) alternative is offered, but I don't immediately see why it's better than just passing a newly created instance to your generic's constructor.

Apparently, the problem originates with how the compiler compiles your generic class. All the type parameters are "erased," which means they are replaced by their bounding class (or Object, in cases like yours where the parameter has no bounding class). The compiler also inserts casts ahead of any variables of parameterized types. The run-time effect is that the virtual machine incurs no additional overhead over code that had been written for Object objects, with casts supplied by the programmer because, in fact, that's the code it's running (but with the Object classes and casts being supplied by the compiler).

It's the same as if your class had been written like this:


and every call your application makes to getT() were coded as ((T)(simpleGeneric.getT()). As you can see, Line 3 isn't creating an instance of the actual class you use to define T (unless that happens to be Object). So, rather than let you create a bunch of Object instances you don't want (and which could not be downcast to anything else), the compiler just doesn't allow you to instantiate parameterized classes.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is indeed because of type erasure, which is how generics are implemented in Java.

One way to solve it is to pass the class of the type to instantiate and then instantiate a T using reflection:
 
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The reasoning behind this error is due to the high priority placed on productivity within the Java platform...
Here T is an unknown type which inherently states that we are unsure if T does contain a default constructor...
If this statement was allowed to happen then the compiler's design would have been more complex and harder to implement considering this scenario which states that for a generic class every type parameter must be default constructible...
 
Marshal
Posts: 80222
424
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rico Felix wrote: . . . does contain a default constructor... . . . ...

Agree, but it is probably not a default constructor. It is probably an ordinary no‑arguments constructor, which the JLS calls a nullary constructor. Nullary in that context refers to the 0‑length arguments list, not to anything being null.
 
siddharth das
Ranch Hand
Posts: 135
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the reply.

During the type erasure process, the Java compiler erases all type parameters and replaces each with its first bound if the type parameter is bounded, or Object if the type parameter is unbounded.

So in this case the type parameter is unbounded ( type parameter will be replaced by Object). So the class would be like below after type erasure process.


Then what is the problem with Java compiler with the Statement ' private Object t = new Object();'

Object class has its default construtor , means we can write new Object().

Thanks!

 
Campbell Ritchie
Marshal
Posts: 80222
424
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

siddharth das wrote: . . .
Object class has its default construtor , means we can write new Object().
. . .

No, it has a no arguments constructor. But many of its subclasses only have constructors with arguments.
 
Stevens Miller
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

siddharth das wrote:
Then what is the problem with Java compiler with the Statement ' private Object t = new Object();'

Object class has its default construtor , means we can write new Object().


There is no problem, in the sense that it would compile and run, but what good is it? In a class using generic parameters, you will want T to be replaced by some class you select at compile time. Yes, that might be Object, but probably not. If the compiler were willing to let you replace "private T t = new T();" with "private Object t = new Object();", then you would not be creating an instance of whatever class you had supplied for the "T" parameter. That is, suppose you used your SimpleGeneric class like this:


You're still going to have a compiler error at Line 10, because Java can't cast an Object to anything else (in this case, it is trying to cast an Object to a MyClass). So, unless you really want T to be Object, there's nothing useful you can do with an instance created by a constructor whose type must be Object after erasure. If you really do want to create Object instances, you don't need parameters at all, and can just code the call to "new Object()" explicitly. I'm guessing that, although it could legally do it, the compiler isn't allowing you to call "new T()" because, with "T" being erased to "Object," some subsequent attempt to access a subclass method or member variable (such as I've written at Line 22 above) would fail, since getT() is returning an Object, not a MyClass.

 
siddharth das
Ranch Hand
Posts: 135
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks a lot for the clarification..
 
Rancher
Posts: 1044
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Rico Felix wrote: . . . does contain a default constructor... . . . ...

Agree, but it is probably not a default constructor.



The term "default constructor" means in C++ the one applicable without arguments, whereas in Java the compiler-provided one.

Default constructor
 
Campbell Ritchie
Marshal
Posts: 80222
424
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ivan Jozsef Balazs wrote: . . .
The term "default constructor" means in C++ . . .

Another pitfall of the, “That's how you do it in C++.” type. At least here it is only nomenclature and won't cause logic errors.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic