在Java中初始化泛型

在Java中初始化泛型,java,initialization,Java,Initialization,假设我有一个名为NodeList的类,它有两个字段,分别是value(typeObject)和index(typeint)NodeList使用一个名为copyNotSyncronized()的方法实现一个名为Copiable的接口 我希望copyNotSincronyzed()版本的NodeList能够识别这个值是否实现了可复制,如果发生这种情况: 使用this.value上的copyNotSincronyzed(),然后 …构建一个新的节点列表对象,该对象具有this.value.copyno

假设我有一个名为
NodeList
的类,它有两个字段,分别是
value
(type
Object
)和
index
(type
int
NodeList
使用一个名为
copyNotSyncronized()
的方法实现一个名为
Copiable
的接口

我希望
copyNotSincronyzed()
版本的
NodeList
能够识别
这个值是否实现了
可复制
,如果发生这种情况:

  • 使用
    this.value上的
    copyNotSincronyzed()
    ,然后
  • …构建一个新的
    节点列表
    对象,该对象具有
    this.value.copynotsCronyzed()
    作为字段
  • 我试着写代码,结果被红色下划线淹没了。从那以后,我知道了两件事:我的Eclipse真的恨我,我仍然不知道如何在Java中使用泛型

    我犯了什么错误

    public class NodeList implements Copiable {
    
        int index;
        Object value;
    
    public NodeList(Object value, int index){
    [...]
    }
    
    NodeList copyNotSincronyzed(){
      NodeList copied;
      if(  onArray.findPositionsOfElement(this.value.getClass().getInterfaces() , this.getClass().getInterfaces()[0])[0] !=-1   )
         // aka if this.value implements the same interface of this class (aka Copiable)
         {
    // Following line features three errors: 
       // Incorrect number of arguments for type Class<T>; it cannot be parameterized with arguments <T, Copiable>
       // T cannot be resolved to a type
       // Syntax error on token "implements", , expected
         Class<T implements Copiable> copiedObject = this.value;
    
    
         copiedObject=copiedObject.copyNotSincronyzed();
         copied = new NodeList( copiedObject , this.index );
         }
       else copied = new NodeList(this.value, this.index);
    
       }  
    
    }
    
    公共类节点列表实现可复制{
    整数指数;
    目标价值;
    公共节点列表(对象值,int索引){
    [...]
    }
    节点列表copyNotSincronyzed(){
    节点列表复制;
    if(onArray.findPositionsOfElement(this.value.getClass().getInterfaces()、this.getClass().getInterfaces()[0])[0]!=-1)
    //aka如果this.value实现了这个类的相同接口(aka Copiable)
    {
    //以下行有三个错误:
    //类型类的参数数量不正确;无法使用参数对其进行参数化
    //T不能解析为类型
    //令牌“implements”上的语法错误,应为
    类copiedObject=this.value;
    copiedObject=copiedObject.copyNotSincronyzed();
    复制=新节点列表(复制对象,this.index);
    }
    else copied=新节点列表(this.value,this.index);
    }  
    }
    
    此值的类型为
    对象
    。您正试图将其放入一个类型
    类中
    。编译器不知道如何执行此操作,因此您会遇到编译错误

    要进行此检查,应使用instanceof运算符,并结合强制转换,如下所示:

    if (this.value instanceof Copiable){ // check that the instance implements an interface
        Copiable asCopiable = (Copiable)this.value; // safely cast to the appropriate type
    }
    

    请注意,您的问题与泛型无关。

    接口是一种类型,就像类一样。因此,当另一个类实现它时,该类的任何对象都可以多态地用作该接口

    这意味着您可以通过使用
    x instanceof Y
    检查该对象是否实现了该接口。它是一个操作符,告诉你x是否是Y,Y可以是类,也可以是接口

    一旦确定对象实现了该类型,就可以使用括号将其转换为接口的类型


    对于代码本身,我建议您参考Vitaliy给出的答案。

    Java有一个接口
    Clonable
    ,允许您通过方法
    Object clone()
    克隆未链接(未同步)的对象。围绕这一点有很多争议,底线是这是令人沮丧的

    创建对象副本的一种广泛接受的方法是使用副本构造函数。这不适用于常规
    对象
    ,因为您事先不知道运行时类。在这种情况下,类似于
    Clonable
    的结构可能仍然有用

    因为
    Clonable
    是遗留的,所以它没有泛型。让我们将
    Copyable
    作为
    Clonable
    的替代品(并将
    clone()
    重命名为
    copyNotSyncronyzed()

    公共接口可复制{
    T copyNotSyncronyzed();
    }
    公共类节点列表实现了可复制{
    private int index;//也要设置为final,除非您计划在某个时候更改它
    private Object value;//也要设置为final,除非您计划在某个时候更改它
    公共节点列表(最终对象值、最终整数索引){
    这个值=值;
    这个指数=指数;
    }
    @凌驾
    公共节点列表copyNotSyncronyzed(){
    if(可复制的值实例){
    对象copiedObject=((可复制)this.value.copyNotSyncronyzed();
    返回新节点列表(copiedObject,this.index);
    }否则
    返回新节点列表(this.value,this.index);
    }
    }
    
    最后一个问题是,如果链接的
    实例不可复制,那么它会复制链接的
    实例,您是否真的对该结构感到满意。这可能会造成危险情况,因为调用
    copyNotSyncronyzed()
    的代码可能期望它与原始代码完全无关


    例如,如果值是
    int[]
    。使用
    copyNotSyncronyzed()
    创建副本,然后更改数组中的一些值,你会发现原始对象数组中的值也发生了更改。

    Copiable
    是一个打字错误。你是说它可以复制吗?(编辑)
    Sincronyzed
    。洛泽尔。。。对对不起,英语不是我的第一语言。
    public interface Copyable<T> {
        T copyNotSyncronyzed();
    }
    
    public class NodeList implements Copyable<NodeList> {
        private int     index; // make final too unless you plan to change it at some point
        private Object  value; // make final too unless you plan to change it at some point
    
        public NodeList(final Object value, final int index) {
            this.value = value;
            this.index = index;
        }
    
        @Override
        public NodeList copyNotSyncronyzed() {
            if (value instanceof Copyable) {
                Object copiedObject = ((Copyable<?>)this.value).copyNotSyncronyzed();
    
                return new NodeList(copiedObject, this.index);
            } else
                return new NodeList(this.value, this.index);
        }
    }