简体   繁体   English

Java中的抽象类和反射

[英]Abstract Classes and Reflection in Java

I have an abstract class which is mostly instantiated as anonymous inner classes, with abstract method implemented there. 我有一个抽象类,大多数实例化为匿名内部类,在那里实现抽象方法。 These instances get passed around, and so at a different place in the code I would like to get a copy of one of these instances, a new instance but with the method implemented the same way. 这些实例被传递,因此在代码中的不同位置我想获得这些实例之一的副本,一个新实例,但实现方法相同。 Here is an example of my code: 这是我的代码示例:

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();
}

I instantiate it like this: 我像这样实例化它:

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

Later, I want a copy, not a reference, of that instance, where update() does the same stuff, but owner will be a different entity. 后来,我想要该实例的副本,而不是引用,其中up​​date()执行相同的操作,但所有者将是不同的实体。 I've tried to use reflection, (.getClass.newInstance()), but I get a java.lang.InstantiationException. 我试过使用反射,(。getClass.newInstance()),但我得到了一个java.lang.InstantiationException。 Why doesn't this work and is there a better way to do what I'm doing? 为什么这不起作用,是否有更好的方法来做我正在做的事情?

You can't instantiate anonymous inner classes through newInstance(). 您无法通过newInstance()实例化匿名内部类。 Non-static inner classes hold a reference to their container Object, you need that Object to create them. 非静态内部类包含对其容器Object的引用,您需要该Object来创建它们。

See Java Tutorial -> Nested Classes 请参阅Java教程 - >嵌套类

That exception is thrown in two cases (from docs ): 两个案例(来自docs )抛出了这个异常:

  • the class object represents an abstract class, an interface, an array class, a primitive type, or void 类对象表示抽象类,接口,数组类,基元类型或void
  • the class has no nullary constructor 该类没有空构造函数

Based on a simple test I did , in your case, the problem is that the resulting anonymous class doesn't have a nullary constructor. 根据我做的简单测试 ,在您的情况下,问题是生成的匿名类没有一个无效的构造函数。

Test code: 测试代码:

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();
}

The first test (with Test ) runs just fine, the second (with Test2 ) fails on the newInstance call with that exception. 第一个测试(使用Test )运行正常,第二个测试(使用Test2 )在具有该异常的newInstance调用上失败。

Sounds like you want to clone the object, implement the interface Cloneable and add in a clone method to define what you need to do to clone said object. 听起来好像要克隆对象,实现Cloneable接口并添加克隆方法来定义克隆所述对象需要做的事情。 In this simple case it would just mean instantiating a new object and setting the id, but I assume your actual implementation is a little more advanced. 在这个简单的例子中,它只是意味着实例化一个新对象并设置id,但我认为你的实际实现更先进一些。

Anonymous inner classes require NO NAME! 匿名内部类需要NO NAME! You shouldn't create an object with the name 'instance' Whenever you need a copy of your abstract class, for example, as an argument for a method, go ahead and use it directly instead of creating and using 'instance' : 您不应该创建名为'instance'的对象每当您需要抽象类的副本(例如,作为方法的参数)时,请直接使用它而不是创建和使用'instance'

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM