Java 重写ArrayList add方法时出现问题
我有一个类正在扩展Java的ArrayList。我目前正在使用Java build 1.6.0_22-b04。看起来像这样: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) {
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提供的方法相反),您需要:
创建一个自定义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());
}