Java 重写ArrayList add方法时出现问题

Java 重写ArrayList add方法时出现问题,java,jdk1.6,Java,Jdk1.6,我有一个类正在扩展Java的ArrayList。我目前正在使用Java build 1.6.0_22-b04。看起来像这样: public class TokenSequence extends ArrayList<Token>{ public TokenSequence (Collection<Token> tokens) { super(tokens); } public void add(Object o) {

我有一个类正在扩展Java的ArrayList。我目前正在使用Java build 1.6.0_22-b04。看起来像这样:

public class TokenSequence extends ArrayList<Token>{
    public TokenSequence (Collection<Token> tokens) {
        super(tokens);  
    }

   public void add(Object o) {
       if (o instanceof Token){ 
           add( (Token)o );
   }
   else if (o instanceof TokenSequence)
       add( (TokenSequence)o );
   else
      add( new Token( o.toString() ) );
   }

}
公共类令牌序列扩展了ArrayList{
公共令牌序列(集合令牌){
超级(代币);
}
公共无效添加(对象o){
如果(o令牌实例){
添加((令牌)o);
}
else if(o令牌序列的实例)
添加((令牌序列)o);
其他的
添加(新令牌(o.toString());
}
}
上面代码中的问题是add(objecto)方法。Java不允许我编译代码,因为它说

"Name clash: The method add(Object) of type TokenSequence has the same erasure as add(E) of type ArrayList<E> but does not override it"
“名称冲突:TokenSequence类型的方法add(Object)与ArrayList类型的add(E)具有相同的擦除,但不覆盖它”
同样的代码在Java build 1.6.0_17-b04下的另一台计算机上也可以正常工作


有人对快速修复有什么想法吗?

将其更改为
公共布尔添加(令牌o)
。(注意返回和参数类型)

为了重写方法,您的重写必须具有完全相同的签名,包括返回类型。
由于您的方法具有不同的返回类型,因此它实际上不会重写基本的
add
方法

它甚至不会编译的原因是,因为它不会重写基方法,所以最终会得到两个不同的
add
方法,这两个方法都可以由派生类调用。
但是,由于类型擦除,它们实际上都使用了
对象
参数,这是非法的。

您需要执行以下操作:

 public boolean add(Token o) {
   }

因为ArrayList是一个泛型

绝对-使用
@Override
注释,最好使用强类型签名:

@Override
public void add(Token token) {
    ...
}

错误消息已经在这里提供了一个很大的提示

我没有尝试过,但我相信正确的实施方式是:

public void add(Token o) {
}

因为
Token
是extends语句中的
E

尝试将@Override注释添加到add()方法中,并确保具有相同的签名(布尔返回类型)

公共类令牌序列扩展了ArrayList{
@凌驾
公共布尔加法(对象e){
返回super.add(e);
}
}
或者,如果希望它是空的,则采用另一个方法param


首先,在当前实现中,当您尝试使用TokenSequence实例调用add函数时,它将进入无限递归。在那种情况下,你是想叫“addAll”吗

第二,忘记

void add(Object)
在您的情况下,需要添加2个方法(如果希望保持一致,请使它们返回布尔值):

并且add(令牌)已经由ArrayList实现

另一方面,如果需要单个方法,可以声明,例如:

public void add(Serializable t)
将为TokenSequence和String调用此方法。 不幸的是,要为令牌执行相同的方法(与ArrayList提供的方法相反),您需要:

  • 确保令牌实现可序列化
  • 将标记强制转换为可序列化
  • i、 e:


    创建一个自定义ArrayList类并重写add方法,如下所示

    public class CustomArrayList<E> extends ArrayList<E>{
    
        @Override
        public boolean add(E e) {
            String temp = (String)e;
            if(temp==null || temp.isEmpty()){
                return false;
            }
    
            return super.add(e);
        }
    }
    
    公共类CustomArrayList扩展了ArrayList{
    @凌驾
    公共布尔加法(E){
    字符串温度=(字符串)e;
    if(temp==null | | temp.isEmpty()){
    返回false;
    }
    返回super.add(e);
    }
    }
    
    对于这个类,下面的示例将只添加1个元素,打印大小为1

    public static void main(String args[]) {
            ArrayList<String> lst = new CustomArrayList<String>();
            lst.add("aaaa");
            lst.add(null);
            lst.add("");
            System.out.println(lst.size());
        }
    
    publicstaticvoidmain(字符串参数[]){
    ArrayList lst=新的CustomArrayList();
    第1条添加(“aaaa”);
    lst.add(空);
    第1条加上(“”);
    System.out.println(lst.size());
    }
    
    返回类型应该是
    boolean
    你确定你的代码没有编译吗?@org:他可能把警告设置为错误。@SLaks-standard-javac甚至没有warn@org: ; 我编辑了我的答案。我添加了add方法的其余部分。如果更改为extends ArrayList或extends ArrayList,则add(…)将中断。问题是,我在1.6.0_17-b04上使用了相同的代码,但在1.6.0_22-b04上出现了中断。这些是不同的计算机。
    add((Serializable)new Token())
    
    public class CustomArrayList<E> extends ArrayList<E>{
    
        @Override
        public boolean add(E e) {
            String temp = (String)e;
            if(temp==null || temp.isEmpty()){
                return false;
            }
    
            return super.add(e);
        }
    }
    
    public static void main(String args[]) {
            ArrayList<String> lst = new CustomArrayList<String>();
            lst.add("aaaa");
            lst.add(null);
            lst.add("");
            System.out.println(lst.size());
        }