我想声明一个属性,该属性包含实现两个不同接口的类的实例。我尝试过这种语法:
private <? extends Interface1 & Interface2> name;
这个:
private <T extends Interface1 & Interface2> T name;
这些都不起作用。有可能吗?语法是什么?我试图避免声明另一个继承自Interface1
和Interface2
的接口。
编辑:
包含此属性的类不应具有任何类型参数。这完全不是这样的:
public class MyClass<T extends Interface1 & Interface2>{
private T name;
...
}
这对那些使用该类的人来说毫无意义。该类不应为泛型,逻辑上也不可能为泛型。
这需要在类声明中进行,例如:
public class TestG<T extends Cloneable & Serializable> {
private T name;
}
一种替代方案是将其设置在方法(但不是变量)中
public class TestG {
public <T extends Cloneable & Serializable> void method(T parameter) {
}
}
变量不能是泛型。
private <T> T var;
不可能——T
在哪一点定义?访问var
时,我无法对分配时使用的内容做出太多假设。
Java允许在类和方法上使用泛型。所以你可以有
private <T implements Cloneable & Serializable> void setVar(T val);
并且您可以拥有类范围的类型T
。
但请始终记住,最终是通过类型擦除来实现的。您总是可以使用getter、setter和强制转换来模拟更复杂的逻辑。如果操作得当,它将为您提供同样多的类型安全性。
获得具有所需类型安全性的变量的最简单方法是只使用两个变量和一个setter来保持它们的同步。
private Serializable vars;
private Cloneable vars;
当然会给你很好的类型安全性。但是是的,它需要4字节的额外内存和一个setter。
以下是您询问的选角方法:
private Object internal_var;
// Implementation notice: do not remove this generic.
// Due to a Java limitation, we *do* want these two constraints!
public <T extends Serializable & Cloneable> void setVar(T val) {
internal_var = val;
}
public Serializable getSerializable() {
return (Serializable) internal_var; // Type checked in setter!
}
public Cloneable getCloneable() {
return (Cloneable) internal_var; // Type checked in setter!
}
// This is the way to use it in a generic getter:
public <T extends Serializable & Cloneable> T getVar(Class<? super T> cls) {
return (T) cls.cast(val);
}
注意,为了在getter中使用T
,我们do需要有一个涉及T的参数。假设我们知道一个类Example implements Serializable, Cloneable
,那么我们就可以使用
// This actually ensures we get an instance of `Example` out:
Example e = instance.getVar(Example.class);
如果是local variable
,则可以在class declaration
或method declaration
中声明该类型参数,并使用该类型:-
public class Demo<T extends Interface1 & Interface2> {
private T t;
}
或:-
public class Demo {
public <S extends Interface1 & Interface2> void demo(S param1) {
S param;
}
}
如果我正确理解你的问题,你想要一个实现这两个ineturface的泛型类。在类定义中声明一个泛型类型参数,并将其作为instace变量类型。
public class Implementor<T extends Interface1<T> & Interface2<T>> {
private T t;
}
编辑:
不能在像这样的实例变量声明中声明类型参数
private <T extends I1 &I2> T t; //this cant be achieved.
但是在方法级别是可能的。
public <T extends I1 & I2> void method(T t){
}