当参数化类型通过层次结构时,在Java中创建泛型类型的实例? [英] Create instance of generic type in Java when parameterized type passes through hierarchies?

查看:122
本文介绍了当参数化类型通过层次结构时,在Java中创建泛型类型的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读这个问题的答案:



我已经实现了Lars Bohl提出的方法。我修改了他的代码,如下所示:

  import java.lang.reflect.ParameterizedType; 
import java.lang.reflect.Type;

public class ParameterizedTypeEg< E> {
public Class< E> getTypeParameterClass(){
类型type = getClass()。getGenericSuperclass();
ParameterizedType paramType =(ParameterizedType)类型;
return(Class< E>)paramType.getActualTypeArguments()[0];
}
private static class StringHome extends ParameterizedTypeEg< String> {
private String _string;
StringHome(String string){
_string = string;

$ b $ public static void main(String [] args)
throws InstantiationException,IllegalAccessException {
String str = new StringHome(my string)。getTypeParameterClass ().newInstance();
String str2 = new ParameterizedTypeEg< String>()。getTypeParameterClass()。newInstance();




$ b

这种方法对于str变量很有效。然后str2被创建,看起来是相同的类型(ParameterizedTypeEg< String>,它与StringHome基本相同)。然而,这种方法不适用于str2,并且当我尝试转换(ParameterizedType)类型时抛出了ClassCastException。



即使对于str2,我也参数化了ParameterizedTypeEg一个String,getGenericSuperclass()返回的东西与str非常不同。此外,在方法str2中将'this'显示为ParameterizedTypeEg,而对于str,'this'是ParameterizedTypeEg $ StringHome。我想这是问题的根源。为什么Java没有看到str2的泛型类型也被确定了?



当参数化类型通过多个级别时,我看到了同样的问题层次?也就是说,B类T>包含A< T>并且我实例化了一个B.在A中,我不能通过使用上面的方法确定A的参数化类型来创建一个String对象。该方法也会在遏制层次结构中产生异常。这导致我一个问题,因为我希望能够通过多层次的遏制和/或继承来传递参数化类型,并且在所有情况下都有相同的方法生成泛型类型的实例。

感谢,
John

解决方案

p>

from

  String str2 = new ParameterizedTypeEg< String>()。getTypeParameterClass ().newInstance(); 

  String str2 = new ParameterizedTypeEg< String>(){}。getTypeParameterClass()。newInstance(); 

这将创建ParameterizedTypeEg的匿名子类。当你调用

  getClass()。getGenericSuperclass(); 

在StringHome上,你得到一个ParameterizedTypeEg< java.lang.String>,这就是你想要的。如果你创建了str2,那么这个调用只是返回Object,所以试图将其转换为paremeterized类型将失败:


异常线程mainjava.lang.ClassCastException:
java.lang.Class不能转换为java.lang.reflect.ParameterizedType

创建一个匿名子类使得这个返回ParameterizedTypeEg< java.lang.String>



这与在Google Guice Guave库中键入Token 类,顺便说一句。你写的,例如

  new TypeToken< List< String>>(){} 




$ b $ p $ 新TypeToken< / p> List< String>>()


I have been reading the answers to the question:

Create instance of generic type in Java?

I have implemented the approach suggested by Lars Bohl. I adapted his code as follows:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class ParameterizedTypeEg<E> {
    public Class<E> getTypeParameterClass() {
        Type type = getClass().getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) type;
        return (Class<E>) paramType.getActualTypeArguments()[0];
    }
    private static class StringHome extends ParameterizedTypeEg<String> {
        private String _string;
        StringHome (String string) {
            _string = string;
        }
    }
    public static void main(String[] args)
        throws InstantiationException, IllegalAccessException {
        String str = new StringHome("my string").getTypeParameterClass().newInstance();
        String str2 = new ParameterizedTypeEg<String>().getTypeParameterClass().newInstance();
    }
}

This approach works fine for the str variable. Then str2 is created with what appears to me to be the same type (ParameterizedTypeEg < String >, which is basically the same thing as a StringHome). However, the approach does not work for str2, and a ClassCastException is thrown when I try to cast (ParameterizedType) type.

Even though for str2, I have parameterized ParameterizedTypeEg with a String, getGenericSuperclass() returns something very different than for str. Also, within methods str2 shows 'this' as a ParameterizedTypeEg, whereas for str, 'this' is a ParameterizedTypeEg$StringHome. I suppose that is the root of the problem. Why does Java not see that the generic type has been determined for str2 also?

I have had what appears to be the same problem when the parameterized type is passed through multiple levels of hierarchy? That is, class B< T > contains A< T > and I instantiate a B. Within A, I cannot create a String object by determining the parameterized type of A using the above approach. The approach produces an exception in the case of a containment hierarchy as well. And this causes me a problem because I want to be able to pass the parameterized type through multiple levels of containment and/or inheritance and have the same approach produce an instance of the generic type in all cases.

Thanks, John

解决方案

With the following change your code will work:

from

  String str2 = new ParameterizedTypeEg<String>().getTypeParameterClass().newInstance();

to

   String str2 = new ParameterizedTypeEg<String>(){}.getTypeParameterClass().newInstance();

This creates an anonymous subclass of ParameterizedTypeEg. When you call

getClass().getGenericSuperclass();

on StringHome, you get a ParameterizedTypeEg < java.lang.String>, which is what you want. If you create str2 as you did, that call simply returns Object, so the attempt to cast it to a paremeterized type fails:

Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

Creating an anonymous subclass makes this return ParameterizedTypeEg < java.lang.String>

This is the same trick that's used in the Type Token class in the Google Guice Guave libraries, btw. You write, for example

new TypeToken<List<String>>() {}

and not

 new TypeToken<List<String>>()  

这篇关于当参数化类型通过层次结构时,在Java中创建泛型类型的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆