简体   繁体   中英

Java reflections - get level by the class name string

I've been looking into Java reflections. This is an example from 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:

    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. 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.

here

foo.hello();

can't work, foo is just an object that does not have a method 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. 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.

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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