Java中的抽象类和反射

时间:2012-05-30 19:55:07

标签: 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 id";
}
abstract void update();
}

我像这样实例化:

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

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

4 个答案:

答案 0 :(得分:6)

您无法通过newInstance()实例化匿名内部类。非静态内部类包含对其容器Object的引用,您需要该Object来创建它们。

请参阅Java Tutorial -> Nested Classes

答案 1 :(得分:2)

在两种情况下抛出该异常(来自docs):

  • 类对象表示抽象类,接口,数组类,基元类型或void
  • 该类没有无效的构造函数

基于a simple test I did,在您的情况下,问题是生成的匿名类没有一个无效的构造函数。

测试代码:

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调用失败时出现该异常。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

someObject.methodToBeUsed(new AbstractClass("This is a test"){
   void update(){
   //do stuff
});