Поиск класса перечисления с использованием Reflection в Java - PullRequest
5 голосов
/ 03 января 2011

Я думаю, что мне нужна помощь в поиске класса перечисления в другом классе с использованием отражения в Java. Я слишком долго боролся с этим. Я прочитал это, а также ряд других постов, и все они заставляют меня поверить, что это должно работать, как показано ниже.

public class ModelActivity {
  public enum AttributeEnumeration { MODELID, MODELURGENCY, MODELDUEDATEANDTIME }

  public static void main(String[] args) {
    // Find the class with the given name
    String className = "ModelActivity";
    Class modelClass = null;
    try {
      // Retrieve the Class with the given className...
      modelClass = Class.forName(className);
    } catch (ClassNotFoundException e) {
      throw new RuntimeException("Class by name '" + className + "' not found.", e);
    }

    // Find the AttributeEnumeration within the class
    String attributeEnumerationClassName = className + ".AttributeEnumeration";
    Class attributeEnumerationClass = null;
    try {
      attributeEnumerationClass = Class.forName(attributeEnumerationClassName);
    } catch (ClassNotFoundException e) {
      throw new RuntimeException("Class by name '" + attributeEnumerationClassName + "' not found.", e);
    }
  }
}

Однако на самом деле происходит то, что modelClass найден правильно, а attributeEnumerationClass нет, то есть я получаю второе исключение ClassNotFoundException следующим образом:

Exception in thread "main" java.lang.RuntimeException: Class by name 'ModelActivity.AttributeEnumeration' not found.
at ModelActivity.main(ModelActivity.java:27)
  Caused by: java.lang.ClassNotFoundException: ModelActivity.AttributeEnumeration
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at ModelActivity.main(ModelActivity.java:25)

Может ли кто-нибудь указать мне - вероятно, очевидную - ошибку на меня. Спасибо.

1 Ответ

10 голосов
/ 03 января 2011

Убедитесь сами:

package foo.bar;

public class Outer{

    public enum Inner{}

    public static void main(final String[] args){
        System.out.println(Inner.class.getName());
    }

}

Вывод:

foo.bar.Outer $ Inner

Внутренние имена классов разделяются с помощью $, не с точкой, поэтому вы хотите ModelActivity$AttributeEnumeration.

КСТАТИ:

Синтаксис $ действителен только для загрузки класса.Используйте точки для доступа к экземплярам класса в источнике следующим образом:

import foo.bar.Outer.Inner;
// ...
private Inner myEnumValue;

или как это:

private foo.bar.Outer.Inner myEnumValue;

Или, скажем так:

assertEquals( // two ways to reference the same class
    foo.bar.Outer.Inner.class,
    Class.forName("foo.bar.Outer$Inner")
);
...