可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a class that is extending Java's ArrayList. I'm currently using Java build 1.6.0_22-b04. Looks like this:
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
"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.
Anyone has any idea on a quick fix?
回答1:
Try adding the @Override annotation to your add() method and make sure to have the same signature (boolean return type)
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
回答2:
Change it to public boolean add(Token o)
. (Note return and parameter type)
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 add
method.
The reason that it won't even compile is that because it doesn't override the base method, you end up with two different add
methods, both of which are callable by your derived class.
However, due to type erasure, they both actually take an Object
parameter, which is illegal.
回答3:
Absolutely - use the @Override
annotation, and ideally use the strongly typed signature:
@Override
public void add(Token token) {
...
}
回答4:
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 Token
is the E
in your extends statement.
回答5:
You need to do:
public boolean add(Token o) {
}
Because ArrayList is a generic.
回答6:
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?
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):
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
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:
- make sure Token implements Serializable
- cast Token to serializable
i.e:
add((Serializable)new Token())
回答7:
create a custom ArrayList class and override the add the method as follows
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
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());
}