Java Generic Class - Determine Type

前端 未结 8 2029
野性不改
野性不改 2020-11-27 12:48

If I am creating a java class to be generic, such as:

public class Foo

How can one determine internally to that class, what \'T\

相关标签:
8条回答
  • 2020-11-27 13:27

    The Problem is that most of the Generic stuff will disappear during compilation.

    One common solution is to save the type during the creation of the Object.

    For a short introduction in the Type Erasure behaviour of java read this page

    0 讨论(0)
  • 2020-11-27 13:28

    I agree with Visage. Generics is for compile-time validation, not runtime dynamic typing. Sounds like what you need is really just the factory pattern. But if your "do this" isn't instantiation, then a simple Enum will probably work just as well. Like what Michael said, if you have a slightly more concrete example, you'll get better answers.

    0 讨论(0)
  • 2020-11-27 13:31

    I've used a similar solution to what he explains here for a few projects and found it pretty useful.

    http://blog.xebia.com/2009/02/07/acessing-generic-types-at-runtime-in-java/

    The jist of it is using the following:

     public Class returnedClass() {
         ParameterizedType parameterizedType = (ParameterizedType)getClass()
                                                     .getGenericSuperclass();
         return (Class) parameterizedType.getActualTypeArguments()[0];
    }
    
    0 讨论(0)
  • 2020-11-27 13:34

    In contrast to .NET Java generics are implemented by a technique called "type erasure".

    What this means is that the compiler will use the type information when generating the class files, but not transfer this information to the byte code. If you look at the compiled classes with javap or similar tools, you will find that a List<String> is a simple List (of Object) in the class file, just as it was in pre-Java-5 code.

    Code accessing the generic List will be "rewritten" by the compiler to include the casts you would have to write yourself in earlier versions. In effect the following two code fragments are identical from a byte code perspective once the compiler is done with them:

    Java 5:

    List<String> stringList = new ArrayList<String>();
    stringList.add("Hello World");
    String hw = stringList.get(0);
    

    Java 1.4 and before:

    List stringList = new ArrayList();
    stringList.add("Hello World");
    String hw = (String)stringList.get(0);
    

    When reading values from a generic class in Java 5 the necessary cast to the declared type parameter is automatically inserted. When inserting, the compiler will check the value you try to put in and abort with an error if it is not a String.

    The whole thing was done to keep old libraries and new generified code interoperable without any need to recompile the existing libs. This is a major advantage over the .NET way where generic classes and non-generic ones live side-by-side but cannot be interchanged freely.

    Both approaches have their pros and cons, but that's the way it is in Java.

    To get back to your original question: You will not be able to get at the type information at runtime, because it simply is not there anymore, once the compiler has done its job. This is surely limiting in some ways and there are some cranky ways around it which are usually based on storing a class-instance somewhere, but this is not a standard feature.

    0 讨论(0)
  • 2020-11-27 13:44

    The whole point of a generic class is that you dont need to know the type that is being used....

    0 讨论(0)
  • 2020-11-27 13:49

    If you know a few specific types that are meaningful, you should create subclasses of your generic type with the implementation.

    So

    public class Foo<T>
    
    public ???? Bar()
    {
        //else condition goes here
    }
    

    And then

    public class DateFoo extends Foo<Date>
    
    public ???? Bar()
    {
        //Whatever you would have put in if(T == Date) would go here.
    }
    
    0 讨论(0)
提交回复
热议问题