简体   繁体   English

Java反射-通过类名称字符串获取级别

[英]Java reflections - get level by the class name string

I've been looking into Java reflections. 我一直在研究Java的思考。 This is an example from Wikipedia http://en.wikipedia.org/wiki/Reflection_(computer_programming ): 这是来自Wikipedia http://en.wikipedia.org/wiki/Reflection_(computer_programming )的示例:

// Without reflection
new Foo().hello();

// With reflection
Class<?> cls = Class.forName("Foo");
cls.getMethod("hello").invoke(cls.newInstance());

I find this a bit counter-intuitive because the method is called before creating an instance. 我发现这有点违反直觉,因为在创建实例之前调用了该方法。

Reflections of course could be useful to call game leves, especially if there are hundreds of them. 当然,反思对于召唤游戏级别可能会有用,特别是如果有数百个级别的话。

EDIT - SOME SOLUTIONS: 编辑-某些解决方案:

Here is a simple example of reflection which works on Android: 这是在Android上运行的简单反射示例:

    try {                
        Class<?> clazz = Class.forName("com.test.Foo");                
        clazz.newInstance();            
    } catch (Exception e) {                
        throw new IllegalStateException(e);            
    }

and the class file 和类文件

public class Foo {

    Foo(){  
        hello();    
    }

    private void hello() {  
        Log.e("FOO", "Hello!");
    }
}

Suppose one wants to call an Activity by reflection: 假设有人想通过反射来调用活动:

Activity activity;
try {                
  Class<?> clazz = Class.forName("com.test.MyLevelActivity");                
  activity = (Activity) clazz.newInstance();            
} catch (Exception e) {                
  throw new IllegalStateException(e);            
}
startActivity(new Intent(this,activity.getClass()));

Suppose a level which contains data and methods should be 'loaded' by reflection: 假设包含数据和方法的级别应通过反射“加载”:

    Level currentLevel;
    try {                
        Class<?> clazz = Class.forName("com.test.Level_1_1");                
        currentLevel = (Level) clazz.newInstance();            
    } catch (Exception e) {                
        throw new IllegalStateException(e);            
    }

    String levelName = currentLevel.getLevelName();
    String result = Integer.toString(currentLevel.processData(3, 7));

    Toast.makeText(this, levelName + " result= " + result, Toast.LENGTH_LONG).show();

Here are the classes: 这些是类:

public abstract class Level {

   public abstract String getLevelName();

   public abstract int processData(int a, int b);

}


public class Level_1_1 extends Level{
   private String levelName = "level 1.1";

   public String getLevelName(){
      return levelName;
   }

   public int processData(int a, int b) {
      return a * b;
  }
} 

I find this a bit counter-intuitive because the method is called before creating an instance 我发现这有点违反直觉,因为在创建实例之前调用了该方法

Sorry, don't think so. 不好意思,别这样。 The method arguments are first evaluated before being passed to "invoke" and hence you end up passing a "new" instance of the Foo class to the "invoke" method of the Method class. 方法参数在传递给“调用”之前首先进行评估,因此最终将Foo类的“新”实例传递给Method类的“调用”方法。 Also, in case you are wondering why call "invoke" on method object, it's because for a given class, you'd create the Method objects only once and all subsequent invocations would rather depend on the "state" of the object rather than the "method" being invoked. 另外,如果您想知道为什么要对方法对象调用“调用”,那是因为对于给定的类,您只能创建一次Method对象,并且所有后续调用都将取决于对象的“状态”,而不是对象的“状态”。 “方法”被调用。

here 这里

foo.hello();

can't work, foo is just an object that does not have a method hello(). 不能工作,foo只是没有方法hello()的对象。

Things that are unfamiliar may seem counter-intuitive, but eventually new idioms become natural. 陌生的事物似乎违反直觉,但最终新习语成为自然。 Just go with the standard approach. 只需采用标准方法即可。

To understand it, consider that the method definition is not part of the object, you write the method once for the class, it "lives" independently of any given object. 要理解它,请考虑方法定义不是对象的一部分,您只需为该类编写一次方法,它就可以独立于任何给定对象而“生存”。 Hence it's quite reasonable for the class to say "hey method, apply yourself in the context of this object, he's one of us" 因此,全班同学说“嘿,方法,将自己应用到这个对象的上下文中,他是我们的一员”是很合理的。

It's not really clear what you mean, but does this help? 目前还不清楚您的意思,但这有帮助吗?

Class<?> cls = Class.forName("Foo");
Method method = cls.getMethod("hello");

Object instance = cls.newInstance();
method.invoke(instance);

you are not calling the method first. 您不是先调用该方法。 you are just definig the method and then invoking it. 您只是定义方法然后调用它。 also, the instance of cls is created before we actually enter invoke. 同样,在实际输入invoke之前创建了cls的实例。 I find the reflections to be a very useful API in java and it is used by almost all the framworks that work on java like struts, log4j, etc. In reflection you always define the method you wanna call and only then work on the actual object you wanna operate on. 我发现反射是Java中非常有用的API,几乎所有在Java上运行的framworks都使用它,例如struts,log4j等。在反射中,您始终定义要调用的方法,然后才在实际对象上工作您想继续操作。

Hope this helps! 希望这可以帮助!

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

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