使用Reflection的Java动态转换

时间:2012-05-28 14:10:24

标签: java reflection

我有以下代码。

父类:

class Parent{

        void a()
        {   
             if(// some logic to check whether child class is calling this method or some other class//)
             System.out.println("Child class is calling..")}
        }

儿童班:

class Child extends Parent{

        void b(){System.out.println(new Parent().a());}
}

其他一些类:

 class Child1{

        void b(){System.out.println(new Parent().a());}
}

这里我从一个子类和其他类调用Parents a()方法。

我的问题是我应该在Parent的一个方法的if块中放入什么逻辑,这样我才能确定哪个类正在调用这个方法。

我有一些代码但是没有用。请帮我解释这段代码中的错误。

if(this.getClass().getClassLoader()
            .loadClass(new Throwable().getStackTrace()[0].getClassName())
            .newInstance() instanceof Parent)
 {
           System.out.println("Child class is calling..")}
 }

2 个答案:

答案 0 :(得分:1)

您有以下选择:

  1. Parent移至其他软件包并对a()进行保护。由于新包中没有其他类,因此只有子类才能调用该方法。

  2. 您可以尝试堆栈跟踪方法,但您搜索的信息不在第一帧中 - 第一帧是您调用new Throwable()的地方。尝试使用第1帧(这是调用a()的地方):

    ...getStackTrace()[1]...
    

    如果您关心性能,则应缓存此结果。

  3. 那就是说,我想知道这段代码的目的是什么。我的直觉是你通过创造一个脆弱的工作来解决一个更深层次的问题,这将导致不同的痛苦。也许你应该告诉我们你想要达到的目标(大局)。

答案 1 :(得分:1)

我想出了类似这样的东西,也许这就是你在寻找什么

package pack;

class Parent {

    void a() {
        //my test
        try{
            throw new Exception();
        }
        catch (Exception e){
            //e.printStackTrace();
            if (!e.getStackTrace()[1].getClassName().equals("pack.Parent"))
                throw new RuntimeException("method can be invoked only in Parrent class");
        }

        //rest of methods body
        System.out.println("hello world");

    }

    public void b(){
        a();
    }

    //works here
    public static void main(String[] args) {
        new Parent().a();
        new Parent().b();
    }
}
class Child extends Parent{
    //RuntimeException here
    public static void main(String[] args) {
        new Parent().a();
        new Parent().b();
    }
}
class Child2{
    //RuntimeException here
    public static void main(String[] args) {
        new Parent().a();
        new Parent().b();
    }
}

忘记提及b方法适用于所有类。希望这就是你想要的。顺便说一句,如果您不想要RuntimeException,请尝试return或抛出其他异常。