【问题标题】:Problem overriding ArrayList add method覆盖 ArrayList 添加方法的问题
【发布时间】:2019-02-28 04:33:26
【问题描述】:

我有一个扩展 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() ) );
   }

}

我在上面代码中的问题是 add(Object o) 方法。 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"

同样的代码在 Java build 1.6.0_17-b04 下的另一台计算机上运行没有问题。

有人对快速修复有任何想法吗?

【问题讨论】:

  • 你确定你的代码不能编译吗?
  • @org:他可能将警告设置为错误。
  • @SLaks 标准 javac 甚至没有警告
  • @org: stackoverflow.com/questions/502614/…;我编辑了我的答案。
  • 我添加了 add 方法的其余部分。如果我更改为 extends ArrayList 或 extends ArrayList 那么 add(...) 将中断。问题是我在 1.6.0_17-b04 上使用了相同的代码,但在 1.6.0_22-b04 上却中断了。这些是不同的计算机。

标签: java jdk1.6


【解决方案1】:

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

public class TokenSequence extends ArrayList<Object> {
  @Override
  public boolean add(Object e) {
    return super.add(e);
  }
}

或者,如果您希望它无效,请使用另一个方法参数。

干杯

【讨论】:

    【解决方案2】:

    将其更改为public boolean add(Token o)。 (注意返回和参数类型)

    要覆盖方法,您的覆盖必须具有完全相同的签名,包括返回类型。
    由于您的方法具有不同的返回类型,因此它实际上并没有覆盖基本的 add 方法。

    它甚至不能编译的原因是因为它没有覆盖基方法,所以你最终会得到两个不同的add 方法,这两个方法都可以被你的派生类调用。
    但是,由于类型擦除,它们实际上都带了一个Object 参数,这是非法的。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 返回类型应该是boolean
      【解决方案4】:

      错误信息已经在这里提供了很大的提示。

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

      public void add(Token o) {
      }
      

      因为 Token 是您的 extends 语句中的 E

      【讨论】:

        【解决方案5】:

        你需要做的:

         public boolean add(Token o) {
           }
        

        因为 ArrayList 是泛型的。

        【讨论】:

          【解决方案6】:

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

          第二,忘掉

          void add(Object)
          

          如果你需要添加 2 个方法(如果你想保持一致,让它们返回布尔值):

          public void add(String o) {
            add(new Token(o.toString()));
          }
          
          public void add(TokenSequence t){
            addAll(t);
          }
          

          并且add(Token)已经被ArrayList实现了

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

          public void add(Serializable t)
          

          TokenSequence 和 String 都会调用此方法。 不幸的是,要为 Token 执行相同的方法(与 ArrayList 提供的方法相反),您将需要:

          1. 确保 Token 实现了 Serializable
          2. 将 Token 转换为可序列化

          即:

          add((Serializable)new Token())
          

          【讨论】:

            【解决方案7】:

            创建一个自定义的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);
                }
            }
            

            使用这个类,下面的例子将只添加 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());
                }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-08-22
              • 2011-03-01
              • 2020-04-29
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多