泛型:创建参数化类参数
如何获取参数化的 Class 对象作为方法参数?
class A<T>
{
public A(Class<T> c)
{
}
void main()
{
A<String> a1 = new A<String>(String.class); // OK
A<List<String>> a2 = new A<List<String>>(List<String>.class); // error
A<List<String>> a3 = new A<List<String>>(Class<List<String>>); // error
}
}
你可能会问,我为什么要这么做?我有一个参数化类,其类型是另一个参数化类,并且其构造函数需要其他类类型作为参数。我知道运行时类没有关于其类型参数的信息,但这不应阻止我在编译时执行此操作。看来我应该能够指定一个类型,例如 List
。还有其他语法可以做到这一点吗?
这是我的真实用例:
public class Bunch<B>
{
Class<B> type;
public Bunch(Class<B> type)
{
this.type = type;
}
public static class MyBunch<M> extends Bunch<List<M>>
{
Class<M> individualType;
// This constructor has redundant information.
public MyBunch(Class<M> individualType, Class<List<M>> listType)
{
super(listType);
this.individualType = individualType;
}
// I would prefer this constructor.
public MyBunch(Class<M> individualType)
{
super( /* What do I put here? */ );
this.individualType = individualType;
}
}
}
这可能吗?
How does one get a parameterized Class object to be used as a method argument?
class A<T>
{
public A(Class<T> c)
{
}
void main()
{
A<String> a1 = new A<String>(String.class); // OK
A<List<String>> a2 = new A<List<String>>(List<String>.class); // error
A<List<String>> a3 = new A<List<String>>(Class<List<String>>); // error
}
}
Why do I want to do that, you may ask? I have a parameterized class whose type is another parameterized class, and whose constructor requires that other class type as an argument. I understand that runtime classes have no information on their type parameters, but that shouldn't prevent me from doing this at compile time. It seems that I should be able to specify a type such as List<String>.class
. Is there another syntax to do this?
Here is my real usage case:
public class Bunch<B>
{
Class<B> type;
public Bunch(Class<B> type)
{
this.type = type;
}
public static class MyBunch<M> extends Bunch<List<M>>
{
Class<M> individualType;
// This constructor has redundant information.
public MyBunch(Class<M> individualType, Class<List<M>> listType)
{
super(listType);
this.individualType = individualType;
}
// I would prefer this constructor.
public MyBunch(Class<M> individualType)
{
super( /* What do I put here? */ );
this.individualType = individualType;
}
}
}
Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
直接投怎么样?
类文字不会有您想要的类型参数。
How about just cast?
Class literals are not going to have the type parameters that you want.
请记住,您不会在运行时获得作为类的 List,正确的方法可能是使用 TypeToken,正如 BalusC 告诉您的那样。如果没有 TypeToken,您无法转换为 List,但您可以创建如下内容:
由于
List_M extends List
这并不像您希望的那样类型安全,但也许已经足够好了。创建实例会像编写一样丑陋,但是您可以使用工厂方法改进它
,然后编写
如果您使用的是 eclipse,代码辅助将帮助您编写丑陋的类 MyBunch2, String>;
当然,在运行时,this.type将是java.util.List,而不是java.util.List
为了得到正确的结果,请选择 TypeToken。
---继续---
您甚至可以创建另一个类
,然后创建实例,因为
必须有一种方法可以在一个类中做到这一点......但我无法弄清楚
Remember you will NOT get a List as a class in runtime, and the right approach would probably be using TypeToken as BalusC told you. Without TypeToken, you can't cast to List, but you can create something like this:
Since
List_M extends List<M>
this is not as typesafe as you may wish, but maybe is nice enough. Creating an instance will be as ugly as writingbut you can improve it with a factory method
and then write
If you are using eclipse, code assist will help you writing the ugly class MyBunch2, String>
Of course, in runtime, this.type will be java.util.List, not java.util.List
To get it right, go for TypeToken.
---Continuation---
You can even make another class
And then create instances as
There must be a way to do that in just one class...but I can't figure it out