Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 创建编译时未知的类的实例_Java_Design Patterns_Inheritance_Reflection - Fatal编程技术网

Java 创建编译时未知的类的实例

Java 创建编译时未知的类的实例,java,design-patterns,inheritance,reflection,Java,Design Patterns,Inheritance,Reflection,我有一个抽象类: public abstract class Room { } 以及编译时未知的继承类,如: public class MagicRoom extends Room { public MagicRoom(){ System.out.println("Creating a MagicRoom."); } public String magic = ""; } 或: 我有一个类,我将从中创建这些类的实例: import java.la

我有一个抽象类:

public abstract class Room {

}
以及编译时未知的继承类,如:

public class MagicRoom extends Room {

    public MagicRoom(){
        System.out.println("Creating a MagicRoom.");
    }

    public String magic = "";
}
或:

我有一个类,我将从中创建这些类的实例:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class MazeGame {

    public static Room makeRoom(Class roomClass) 
        throws IllegalArgumentException, InstantiationException, 
            IllegalAccessException, InvocationTargetException, 
            SecurityException, NoSuchMethodException{

        Constructor c = roomClass.getConstructor();
        return c.newInstance();

    }

}
MakerRoom是我试图创建一个从Room继承的类,我在编译时不知道它的类型,但我不确定将什么作为它的返回类型而不是Room。因为MakerRoom返回一个文件室,所以如果我尝试使用属于继承类的字段,就会出现异常:

import java.lang.reflect.InvocationTargetException;

public class FactoryTest {

    public static void main(String[] args) 
        throws IllegalArgumentException, SecurityException, 
            InstantiationException, IllegalAccessException, 
            InvocationTargetException, NoSuchMethodException{

        MazeGame game = new MazeGame();

        Room magicRoom = MazeGame.makeRoom(MagicRoom.class);

        /*
         * Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
         * magic cannot be resolved or is not a field
         */

        magicRoom.magic = "a"; 

    }
}

使该方法通用:

public static <T extends Room> T makeRoom(Class<T> roomClass) 
    throws IllegalArgumentException, InstantiationException, 
        IllegalAccessException, InvocationTargetException, 
        SecurityException, NoSuchMethodException{

    // This is enough, if you have 0-arg constructor in all your subclasses
    return roomClass.newInstance();
}

您必须将房间对象强制转换为MagicRoom

MagicRoom magicRoom = (MagicRoom) MazeGame.makeRoom(MagicRoom.class);
此外,我知道这只是一个示例,但您应该将这些属性设置为私有,并使用访问器/变异器方法

e、 g


我不明白,这个类是已知的,它是
MagicRoom
?Rohit的答案实际上比我的答案更好,但你仍然应该避免使用公共属性。谢谢你的答案,你将属性公开是正确的。经过测试并被接受,很遗憾,我没有足够的声望点数来提高答案的投票率。请单击答案评级下方的勾号以接受答案。我以为任何人都可以投票?
MagicRoom magicRoom = MazeGame.makeRoom(MagicRoom.class);  
MagicRoom magicRoom = (MagicRoom) MazeGame.makeRoom(MagicRoom.class);
public class MagicRoom extends Room {

  public MagicRoom(){
    System.out.println("Creating a MagicRoom.");
  }

  private String magic = "";

  public String getMagic() {
    return this.magic;
  }

  public void setMagic(String magic) {
    this.magic = magic;
  }

}