Java 覆盖 ArrayList 添加方法的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4196149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:28:04  来源:igfitidea点击:

Problem overriding ArrayList add method

javajdk1.6

提问by Marquinio

I have a class that is extending Java's ArrayList. I'm currently using Java build 1.6.0_22-b04. Looks like this:

我有一个扩展 Java 的 ArrayList 的类。我目前正在使用 Java 版本 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() ) );
   }

}

My problem in the above code is the add(Object o) method. Java won't let me compile the code because it says

我在上面代码中的问题是 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"

This same code works with no problems in another computer under Java build 1.6.0_17-b04.

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

Anyone has any idea on a quick fix?

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

回答by SLaks

Change it to public boolean add(Token o). (Note return and parameter type)

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

In order to override a method, your override must have the exact same signature, including the return type.
Since your method has a different return type, it doesn't actually override the base addmethod.

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

The reason that it won't even compile is that because it doesn't override the base method, you end up with two different addmethods, both of which are callable by your derived class.
However, due to type erasure, they both actually take an Objectparameter, which is illegal.

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

回答by Amir Raminfar

You need to do:

你需要做:

 public boolean add(Token o) {
   }

Because ArrayList is a generic.

因为 ArrayList 是一个泛型。

回答by Jon Skeet

Absolutely - use the @Overrideannotation, and ideally use the strongly typed signature:

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

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

回答by Powerlord

The error message already provided a large hint here.

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

I haven't tried it, but I believe the correct implementation would be:

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

public void add(Token o) {
}

because Tokenis the Ein your extends statement.

因为TokenE在您的扩展语句中。

回答by chzbrgla

Try adding the @Override annotation to your add() method and make sure to have the same signature (boolean return type)

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

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

Or if you want it to be void, take another method param.

或者,如果您希望它为空,请采用另一个方法参数。

cheers

干杯

回答by Yuriy

First of all, in the current implementation it will go to infinite recursion when you will try to call add function with instance of TokenSequence. Did you mean to call "addAll" in that case?

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

Second, forget about

二、忘记

void add(Object)

in you case you need to add 2 methods (make them return boolean, if you want to be consistent):

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

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

public void add(TokenSequence t){
  addAll(t);
}

and the add(Token) is already implemented by ArrayList

并且 add(Token) 已经由 ArrayList 实现

on the other hand, if you want a single method, you can declare, for example:

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

public void add(Serializable t)

this method will be called for both TokenSequence and String. unfortunately to make the same method executed for Token (as oppose to the one provided by ArrayList), you will need:

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

  1. make sure Token implements Serializable
  2. cast Token to serializable
  1. 确保 Token 实现 Serializable
  2. 将令牌转换为可序列化

i.e:

IE:

add((Serializable)new Token())

回答by WhyJava

create a custom ArrayList class and override the add the method as follows

创建一个自定义 ArrayList 类并覆盖添加方法如下

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);
    }
}

with this class, following example will add only 1 element and print size as 1

使用此类,以下示例将仅添加 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());
    }