2

我有一个抽象类,它主要被实例化为匿名内部类,在那里实现了抽象方法。这些实例被传递,因此在代码中的不同位置,我想获得其中一个实例的副本,一个新实例,但方法以相同的方式实现。这是我的代码示例:

public abstract class AbstractClass {
String id;
Entity owner;
public AbstractClass(String id){
    this.id=id;
} 
public Mover(){
    id="This is an id";
}
abstract void update();
}

我这样实例化它:

AbstractClass instance= new AbstractClass("This is a test"){
void update(){
//do stuff
}
}

稍后,我想要该实例的副本,而不是引用,其中 update() 执行相同的操作,但所有者将是不同的实体。我尝试使用反射 (.getClass.newInstance()),但我得到了 java.lang.InstantiationException。为什么这不起作用,有没有更好的方法来做我正在做的事情?

4

4 回答 4

6

您不能通过 newInstance() 实例化匿名内部类。非静态内部类持有对其容器对象的引用,您需要该对象来创建它们。

请参阅Java 教程 -> 嵌套类

于 2012-05-30T19:58:36.630 回答
2

该异常在两种情况下引发(来自docs):

  • 类对象表示抽象类、接口、数组类、原始类型或 void
  • 该类没有空构造函数

根据我所做的一个简单测试,在您的情况下,问题是生成的匿名类没有空构造函数。

测试代码:

import java.util.*;
import java.lang.*;

class Main
{
        public static void main (String[] args) throws java.lang.Exception
        {
            {
            Test thing = new Test(){ public void update(){ id="updated"; } };

            thing.update();

            Test thang = thing.getClass().newInstance();

            System.out.println( thing.id+" "+thang.id );
            }

            {
            Test2 thing = new Test2("name"){ public void update(){ id="updated"; } };

            thing.update();

            Test2 thang = thing.getClass().newInstance();

            System.out.println( thing.id+" "+thang.id );
            }

        }
}

abstract class Test{
    public String id;
    Test(){ id = "Empty"; }
    abstract public void update();
}

abstract class Test2{
    public String id;
    Test2(String me){ id = me; }
    abstract public void update();
}

第一个测试 (with Test) 运行得很好,第二个测试 (with ) 在调用中Test2失败并出现该异常。newInstance

于 2012-05-30T20:09:50.883 回答
1

匿名内部类需要 NO NAME!你不应该创建一个名为'instance'的对象 每当你需要抽象类的副本时,例如,作为方法的参数,直接使用它而不是创建和使用'instance'

someObject.methodToBeUsed(new AbstractClass("This is a test"){
   void update(){
   //do stuff
});
于 2012-05-30T20:30:46.633 回答
1

听起来你想克隆对象,实现接口 Cloneable 并添加一个克隆方法来定义你需要做什么来克隆所述对象。在这个简单的情况下,它只是意味着实例化一个新对象并设置 id,但我假设您的实际实现更高级一些。

于 2012-05-30T19:59:01.273 回答