2013-11-01 50 views
0

说我有两类:在运行时更改类的所有实例的方法

AnimalPen.java

public class AnimalPen { 

    private ArrayList<Animal> animals; 

    public AnimalPen() { 
     animals = new ArrayList<Animal>(); 
     animals.add(new Dog("Freddy")); 
     animals.add(new Dog("Doggy")); 

     for (Animal a : animals) { 
      animal.makeSound(); 
     } 
    } 

} 

Dog.java

public class Dog extends Animal { 

    public Dog(String name) { 
     super(name); 
    } 

    @Override 
    public void makeSound() { 
     System.out.println("Woof"); 
    } 
} 

有什么可能的方式使用反射改变什么狗makeSound()没有修改任何这些classe S'例如(这只是一个建议,我没有反映最了解),我做了一个名为Dog扩展Animal类,然后在运行时交换Dog.java与我创造这么一贴上面每一次new Dog()被调用,它会创建一个我的狗的新实例,而不是上面写的那个。我需要这种方式,以便我不需要知道什么时候创建了Dog的新实例,但是他们使用的是我通过修改makeSound()而不是仅打印出“Woof”的那个类。

举一个更好的例子,作为一个实验,我想修改的Minecraft服务器,而无需修改服务器本身的源代码。我通过CraftBukkit将我的代码加载到JVM中,我希望通过修改实体类中的方法并将它们加载到服务器中来直接更改实体的行为方式。我知道这是可以通过反思来完成的,我只是或多或少地想知道是否有可能在运行时将整个班级与其修改后的版本“交换”。

+0

听起来像您对Strategy模式感兴趣。 http://en.wikipedia.org/wiki/Strategy_pattern 可能的工厂模式。你的解释很不清楚,请解释你想达到什么样的情况,而不是试图解释一个半解的解决方案。 –

+1

AOP和Java代理可能会让你这样做,但也许可以在没有反射或这些(复杂)概念的情况下满足你的实际需求。你能谈谈你想要满足的真实场景,也许我们可以帮助确定一个直接的方法吗? –

+0

@MarkElliot我更新了一个我试图完成的例子。现在我意识到这一点,我一直试图通过一个复杂的例子来问一个简单的问题 – user2249516

回答

3

不,你不能在运行时用反射改变方法。可以使用反射来调用方法,访问字段等。在运行时没有可能改变Java类的技术,这基本上意味着将源重新编译为字节码。

+0

可以使用各种调试器功能,但它们涉及到即时重新编译类或拦截调用和模拟对类的更改。 –

相关问题