Java中的抽象类和反射

Java中的抽象类和反射,java,reflection,abstract-class,Java,Reflection,Abstract Class,我有一个抽象类,它大部分被实例化为匿名内部类,并在那里实现了抽象方法。这些实例被传递,因此在代码中的另一个地方,我希望获得其中一个实例的副本,一个新实例,但方法以相同的方式实现。下面是我的代码示例: public abstract class AbstractClass { String id; Entity owner; public AbstractClass(String id){ this.id=id; } public Mover(){ id="This is an

我有一个抽象类,它大部分被实例化为匿名内部类,并在那里实现了抽象方法。这些实例被传递,因此在代码中的另一个地方,我希望获得其中一个实例的副本,一个新实例,但方法以相同的方式实现。下面是我的代码示例:

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.InstanceException。为什么这不起作用?有没有更好的方法来完成我正在做的事情?

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


请参见

听起来您想克隆对象,实现接口Cloneable并添加克隆方法来定义克隆所述对象所需的操作。在这个简单的例子中,它只意味着实例化一个新对象并设置id,但我假设您的实际实现更高级一点。

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

  • class对象表示抽象类、接口、数组类、基元类型或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();
}

第一个测试(使用
test
)运行正常,第二个测试(使用
Test2
)在
newInstance
调用中失败,但有一个例外。

匿名内部类不需要名称!不应创建名为“instance”的对象 例如,当您需要抽象类的副本作为方法的参数时,请直接使用它,而不是创建和使用“实例”:


我将把这些修改实体的类与实体本身分开。也就是说,update方法获取一个实体作为参数,而不是将其作为类字段。@Luciano:这是一个好主意,我可能最终会这样做。是的,但“我需要做什么来克隆所述对象”是我不知道的,因为你不能构造抽象类的实例。如果我给超类一个空构造函数,我仍然得到了错误。@TheTestator在我的例子中,它似乎起了作用,因为我是在一个静态方法中创建匿名类的。Sean的回答解释了为什么在非静态上下文中会出现错误。是的,对不起,我就是这么做的,“实例”对象就是一个例子
someObject.methodToBeUsed(new AbstractClass("This is a test"){
   void update(){
   //do stuff
});