声明扩展2个不同接口的类型属性

时间:2012-11-17 10:03:58

标签: java generics types attributes covariance

我想声明包含实现2个不同接口的类实例的属性。我试过这种语法:

private <? extends Interface1 & Interface2> name;

和此:

private <T extends Interface1 & Interface2> T name;

这些都不起作用。可能吗?语法是什么?我试图避免声明继承自Interface1Interface2的其他接口。


编辑:

包含此属性的类不应包含任何类型参数。这不是这样的:

public class MyClass<T extends Interface1 & Interface2>{
    private T name;
    ...
}

对于那些使用该课程的人来说没有任何意义。不希望该类不可能是通用的。

4 个答案:

答案 0 :(得分:4)

需要进入类声明,例如:

public class TestG<T extends Cloneable & Serializable> {
    private T name;
}

另一种方法是在方法中设置它(但不是变量)

public class TestG {
    public <T extends Cloneable & Serializable> void  method(T parameter) {
    }
}

答案 1 :(得分:2)

您可以在class declarationmethod declaration中声明该类型参数,如果是local variable,则使用该类型: -

public class Demo<T extends Interface1 & Interface2> {
    private T t;
} 

或: -

public class Demo {
    public <S extends Interface1 & Interface2> void demo(S param1) {
        S param;
    }
}

答案 2 :(得分:2)

变量不能是通用的。

private <T> T var;

是不可能的 - 此时T已定义?访问var时,我无法对我在分配时使用的内容做出太多假设。

Java允许在方法上使用泛型。所以你可以拥有

private <T implements Cloneable & Serializable> void setVar(T val);

您可以拥有班级类型T

但始终记住最终,它是通过类型擦除实现的。您总是可以使用getter,setter和casts来模拟更复杂的逻辑。如果操作正确,它将为您提供尽可能多的类型安全。

获取具有所需类型安全性的变量的最简单方法是使用两个变量,并使用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,我们需要有一个涉及T的参数。 假设我们知道一个班级Example implements Serializable, Cloneable,我们就可以使用

// This actually ensures we get an instance of `Example` out:
Example e = instance.getVar(Example.class);

答案 3 :(得分:1)

如果我正确理解你的问题,你需要一个实现两个inetrfaces的泛型类。 在类定义中声明泛型类型参数,并将其作为实例变量类型。

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){

  }