Создавать вложенные статические классы с помощью класса Class.forName
У меня есть nested static class
как:
package a.b
public class TopClass {
public static class InnerClass {
}
}
Я хочу создать экземпляр с помощью Class.forName()
, но он вызывает ClassNotFoundException
.
Class.forName("a.b.TopClass"); // Works fine.
Class.forName("a.b.TopClass.InnerClass"); // raises exception
TopClass.InnerClass instance = new TopClass.InnerClass(); // works fine
Что не так в моем коде?
Удо.
Ответы
Ответ 1
Вложенные классы используют "$" в качестве разделителя:
Class.forName("a.b.TopClass$InnerClass");
Таким образом, JRE может использовать точки для определения пакетов, не беспокоясь о вложенных классах. Вы заметите это, если посмотрите на сгенерированный файл класса, который будет TopClass$InnerClass.class
.
(EDIT: Извинения за оригинальную неточность. Голова застряла в среде .NET, пока я не подумал об именах файлов...)
Ответ 2
попробуйте
Class.forName("a.b.TopClass$InnerClass");
Ответ 3
Доступ к внутренним классам осуществляется через знак доллара:
Class.forName("a.b.TopClass");
Class.forName("a.b.TopClass$InnerClass");
Ответ 4
Внутренний класс всегда доступен через знак доллара, потому что, когда компилятор java компилирует исходный код java, он генерирует файл .class(байтовый код).
если есть только один класс, например Hello.java, и этот класс является внешним классом, тогда компилятор java при компиляции генерирует файл Hello.class, но если этот класс имеет внутренний класс HelloInner, тогда java-компилятор генерирует d Hello $HelloInner.class(байтовый код).
поэтому байт-код всегда выглядит как следующий фрагмент с именем Outer.java:
public class Outer
{
public var;//member variable
Outer()//constructor
{
}
class Inner1
{
class Inner2
{
}
}
}
, поэтому байтовый код: Outer $Inner1 $Inner2.class
почему мы используем $sign для доступа к внутреннему классу.:)