Отражения Java - получить уровень по строке имени класса - PullRequest
1 голос
/ 19 августа 2011

Я изучал отражения Java.Это пример из Википедии 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());

Я считаю это немного нелогичным, потому что метод вызывается перед созданием экземпляра.

Размышления, конечно, могут быть полезны для вызоваигровые уровни, особенно если их сотни.

РЕДАКТИРОВАТЬ - НЕКОТОРЫЕ РЕШЕНИЯ:

Вот простой пример отражения, которое работает на Android:

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

ифайл класса

public class Foo {

    Foo(){  
        hello();    
    }

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

Предположим, что кто-то хочет вызвать Activity с помощью отражения:

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()));

Предположим, что уровень, содержащий данные и методы, должен быть «загружен» с помощью отражения:

    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();

Вот классы:

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;
  }
} 

Ответы [ 4 ]

7 голосов
/ 19 августа 2011

Я нахожу это немного нелогичным, потому что метод вызывается перед созданием экземпляра

Извините, не думайте так. Аргументы метода сначала оцениваются перед передачей в «invoke», и, следовательно, вы в конечном итоге передаете «новый» экземпляр класса Foo методу «invoke» класса Method. Кроме того, в случае, если вам интересно, зачем вызывать «invoke» для объекта метода, это потому, что для данного класса вы создадите Method объекты только один раз, и все последующие вызовы скорее будут зависеть от «состояния» объекта, а не чем метод, который вызывается.

3 голосов
/ 19 августа 2011

здесь

foo.hello();

не может работать, foo - это просто объект, у которого нет метода hello ().

То, что незнакомо, может показаться нелогичным, нов конце концов новые идиомы становятся естественными.Просто перейдите к стандартному подходу.

Чтобы понять это, учтите, что определение метода не является частью объекта, вы пишете метод один раз для класса, он «живет» независимо от любого данного объекта.Следовательно, вполне разумно, чтобы класс сказал: «Эй, метод, примените себя в контексте этого объекта, он один из нас»

2 голосов
/ 19 августа 2011

Не совсем понятно, что вы имеете в виду, но помогает ли это?

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

Object instance = cls.newInstance();
method.invoke(instance);
1 голос
/ 19 августа 2011

вы не вызываете метод первым.вы просто определяете метод и затем вызываете его.также экземпляр cls создается до того, как мы действительно введем invoke.Я считаю, что отражения - это очень полезный API в java, и он используется почти во всех фреймворках, работающих на java, таких как struts, log4j и т. Д. В отражении вы всегда определяете метод, который хотите вызвать, и только затем работаете с реальным объектомВы хотите оперировать.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...