java Java泛型字段声明
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32008752/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java generic field declaration
提问by succcubbus
In a class without generic types I want to declare a rather complex generic field similar to these:
在没有泛型类型的类中,我想声明一个与这些类似的相当复杂的泛型字段:
public class Client {
private Map<Class<T extends Serializable>, List<Consumer<S extends T>>> classToConsumerTry1;
private <T extends Serializable, S extends T> Map<Class<T>, List<Consumer<S>>> classToConsumerTry2;
}
promblem is the java compiler won't let me :)
问题是java编译器不会让我:)
So my question is how do I correctly introduce T and S without adding types to my class Client.
所以我的问题是如何在不向我的类 Client.js 中添加类型的情况下正确引入 T 和 S。
My goal is to enforce the Class
being a subtype of Serializable
and the Consumer
being a subtype of the class you chose for Class
.
我的目标是强制Class
成为您选择的类的子类型Serializable
和Consumer
子类型Class
。
采纳答案by Eran
You can't. Your only option is to declare the generic type parameters in your Client
class declaration. If your Client
class has no generic type parameters, its members can't be generic. You must use actual types in the declaration of your class members.
你不能。您唯一的选择是在Client
类声明中声明泛型类型参数。如果您的Client
类没有泛型类型参数,则其成员不能是泛型的。您必须在类成员的声明中使用实际类型。
回答by Konstantin Yovkov
You have to somewhere introduce the type-parameter, so that you can use them in the definition for your class members.
您必须在某处引入类型参数,以便您可以在类成员的定义中使用它们。
Introducing a type-parameter can be done only on a class-level, or on a method-level. In your case, it should be on class-level:
只能在类级别或方法级别上引入类型参数。在您的情况下,它应该在类级别:
public class Client<T extends Serializable, S extends T> {
private Map<Class<T>, List<Consumer<S>>> classToConsumerTry1;
private Map<Class<T>, List<Consumer<S>>> classToConsumerTry2;
}
This, however, implies that for both members (classToConsumerTry1
and classToConsumerTry2
), T
and S
are the same. If you want them to be different, the you will have to get these two values from two different classes, both of which are parameterized with separate type-parameters.
然而,这意味着对于两个成员 (classToConsumerTry1
和classToConsumerTry2
),T
和S
是相同的。如果您希望它们不同,则必须从两个不同的类中获取这两个值,这两个类都使用单独的类型参数进行参数化。
回答by Philip Voronov
You can not do it directly on the field, but you can maintain your types policy by generic methods (they can exist even in non-generic class):
你不能直接在现场做,但你可以通过泛型方法维护你的类型策略(它们甚至可以存在于非泛型类中):
@SuppressWarnings("rawtypes")
private Map<Class, List> map;
public <T extends Serializable> void put(Class<T> key, List<Consumer<? extends T>> value) {
map.put(key, value);
}
@SuppressWarnings("unchecked")
public <T extends Serializable> List<Consumer<? extends T>> get(Class<T> key) {
return map.get(key);
}
回答by AllDayAmazing
You can't the way you want it done. But you can set as an Object
and cast. Other hacky answers include using a List
of <? extends Serializable>
(but this only works for one extends
) and then add()
your item or an internal class that does something like:
你不能按照你想要的方式完成。但是你可以设置为 anObject
和 cast。其他 hacky 答案包括使用List
of <? extends Serializable>
(但这仅适用于 one extends
),然后使用add()
您的项目或执行以下操作的内部类:
private class Foo<T> {
T obj;
}
so you can access/mutate obj
internally.
所以你可以在obj
内部访问/变异。
回答by rogerdpack
As a note it is possible to declare a class type as a field (since google sends me here)
请注意,可以将类类型声明为字段(因为谷歌将我发送到这里)
Class<? extends MyInterface> myCurrentClass = MyImplementation.class;