Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / July 2007

Tip: Looking for answers? Try searching our database.

Get the parameterized type of a subclass

Thread view: 
cdvr - 21 Jul 2007 17:08 GMT
Hi,
  I have the following setup....

public interface Foo<T> { ....}

public abstract class AbstractFoo<T> implements Foo<T> {
   public void printParamType() {
          // print the actual type of T
   }
}

public class MyFoo extends AbstractFoo<Blah> {

   public void static main(String[] args) {
          MyFoo f = new MyFoo();
          f.printParamType();
    }
}

What I'd like to get is the type "Blah"....how can I get that Type or
reference to the Class object at run-time?

Thanks
nebulous99@gmail.com - 21 Jul 2007 17:50 GMT
> What I'd like to get is the type "Blah"....how can I get that Type or
> reference to the Class object at run-time?

public interface Foo<T> { ... }

public abstract class AbstractFoo<T> implements Foo<T> {
   private Class<T> paramType;

   protected AbstractFoo (Class<T> paramType) {
       this.paramType = paramType;
   }

   public void printParamType() {
          System.out.println(paramType);
   }
}

public class MyFoo extends AbstractFoo<Blah> {
   public MyFoo () {
       super(Blah.class);
   }

   public void static main(String[] args) {
          MyFoo f = new MyFoo();
          f.printParamType();
   }
}

You might want to specify printParamType in the interface, or better
yet make it getParamType and leave it up to the caller what to do with
the Class object. Of course the param type class object has to be
passed to the AbstractFoo constructor by its subclasses. Any instance
can be queried regarding the param type. Subtypes that are still
parametrized can continue to ask for it in their constructors to pass
to the superclass constructor; ones that are not parametrized,
extending Superclass<SpecificType>, can call super(SpecificType.class)
in their constructors.
Piotr Kobzda - 21 Jul 2007 22:10 GMT
> public abstract class AbstractFoo<T> implements Foo<T> {
>     public void printParamType() {
>            // print the actual type of T

        Class subclass = getClass();
        for(Class c; (c = subclass.getSuperclass())
                != AbstractFoo.class; subclass = c);
        ParameterizedType type = (ParameterizedType)
                subclass.getGenericSuperclass();
        System.out.println(type.getActualTypeArguments()[0]);

>     }
> }
[quoted text clipped - 9 lines]
> What I'd like to get is the type "Blah"....how can I get that Type or
> reference to the Class object at run-time?

The sample code above shows how to do that.  It assumes that you pass an
actual type directly from the superclass (as in a case of your MyFoo
class).  However, in general, it may be more complex (e.g. actual type
passed from non direct subclass), or even impossible to infer what the
actual type argument type is (type erasure).  BTW -- Maybe the later
limitation will become weaker soon, thanks to the Neal Gafter proposal
of making generic types fully reifiable.

piotr
Roedy Green - 22 Jul 2007 03:48 GMT
>What I'd like to get is the type "Blah"....how can I get that Type or
>reference to the Class object at run-time?

Type erasure says you can't.  That information is erased at compile
time. It is strictly for compile-time checking.

see http://mindprod.com/jgloss/generics.html

Type erasure was done to make generics easy for the JVM makers to
implement.  It also hoped for strict compatibility with JDK 1.4.
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Piotr Kobzda - 22 Jul 2007 11:00 GMT
>> What I'd like to get is the type "Blah"....how can I get that Type or
>> reference to the Class object at run-time?
>
> Type erasure says you can't.  That information is erased at compile
> time. It is strictly for compile-time checking.

Not all information about generics is being erased at compile time.

> see http://mindprod.com/jgloss/generics.html

You probably will need to update a bit your valuable glossary page,
because not the whole true is there.

There is a lot of generic information preserved for runtime in a class
files.  In particular, there is a full information about generic
declaration preserved.  Type erasure, in general, affects a direct use
of a generic types in a code only.  (Of course, the method declarations,
and many others language elements are affected also, but that's not
important here I think).

For example, if you put the following line into some method body:

    List<String> list = new ArrayList<String>();

there is no information at runtime that a String is the actual type
argument for both List, and ArrayList.

But when you put the above line into a class' declaration body (making a
field), then the information about actual the type argument type of a
List is preserved in that field declaring class file
(Field.getGenericType() allows to access it).

There is still no full information preserved about actual type argument
used for ArrayList.  However, we can preserve that info also in
ArrayList subclass declaration (that's what the OP did).

So when we change our field declaration to:

    List<String> list = new ArrayList<String>() {};

There is all information about List and ArrayList actual type arguments
present at runtime (retrievable the way demonstrated in my previous post
to this thread).

> Type erasure was done to make generics easy for the JVM makers to
> implement.  It also hoped for strict compatibility with JDK 1.4.

The type erasure was mainly designed to allow binary backward
compatibility.  The generic information already preserved do not breaks
that.  There was not clear idea previously on how to add more info
without breaking the compatibility.  But now we have the Neal Gafter's
proposal (mentioned in my previous post) to allow fully reified generic
types to coexist with these that we have currently, still without
breaking binary backward compatibility.

For more details see:
http://gafter.blogspot.com/2006/11/reified-generics-for-java.html
http://tech.puredanger.com/java7#reified

piotr


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.