Java: как проверить, является ли объект экземпляром нестатического внутреннего класса, независимо от внешнего объекта?
Если у меня есть внутренний класс, например.
class Outer{
class Inner{}
}
Есть ли способ проверить, является ли произвольный Object
экземпляр любого Inner
, независимо от его внешнего объекта? instanceof
дает false, когда объекты не являются Inner
из того же Outer
. Я знаю, что обходным путем является создание Inner
статического класса, но мне интересно, возможно ли, что я спрашиваю.
Пример:
class Outer{
Inner inner = new Inner();
class Inner{}
public boolean isInner(Object o){
return o instanceof Inner;
}
}
Outer outer1 = new Outer();
Outer outer2 = new Outer();
boolean answer = outer1.isInner(outer2.inner); //gives false
Ответы
Ответ 1
А как насчет?
public static boolean isInnerClass(Class<?> clazz) {
return clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers());
}
Метод isMemberClass()
будет проверять, является ли метод членом (а не анонимным или локальным классом), а второе условие будет проверять что ваш класс-член не является статическим.
Кстати, документация объясняет различия между локальными, анонимными и вложенными классами.
Вложенные классы делятся на две категории: статические и нестатические. Вложенные классы, объявленные static, просто называются статическими вложенными классами. Нестатические вложенные классы называются внутренними классами.
Ответ 2
вы всегда можете:
getClass().getName()
и выполните сравнение строк.
РЕДАКТИРОВАТЬ: для учета наследования (среди внутренних классов? кто это сделает?!) вы всегда можете прокручивать через getSuperclass()
и проверять их, а также идти после реализованных интерфейсов.
Ответ 3
Вы пытались использовать getEnclosingClass():
Возвращает сразу входящий класс базового класса. Если базовый класс является классом верхнего уровня, этот метод возвращает null.
Outer.class.equals(object.getClass().getEnclosingClass())
Получение правильного закрывающего класса объекта, IMHO не так просто. Прочитайте этот.
В некоторой степени от взлома будет:
object.getClass().getName().contains("Outer$");
Ответ 4
o instanceof Outer.Inner
дает false
, когда o
является экземпляром Inner
любого Outer
, отличного от того, из которого вы его вызываете.
Это не происходит для меня - я получаю true
для o instanceof Inner
независимо от того, какой конкретный экземпляр окружения Outer
принадлежит o
:
class Outer {
class Inner {}
void test() {
// Inner instance that belongs to this Outer
Inner thisInner = new Inner();
// Inner instance that belongs to a different Outer
Outer other = new Outer();
Inner otherInner = other.new Inner();
// both print true
System.out.println(thisInner instanceof Inner);
System.out.println(otherInner instanceof Inner);
}
public static void main(String[] args) {
new Outer().test();
}
}
Протестировано как с Java 6, так и с 7.
Ответ 5
Метод java.lang.Class.getEnclosingClass()
возвращает сразу входящий класс базового класса. Если этот класс является классом верхнего уровня, этот метод возвращает null.
В следующем примере показано использование метода java.lang.Class.getEnclosingClass():
import java.lang.*;
public class ClassDemo {
// constructor
public ClassDemo() {
// class Outer as inner class for class ClassDemo
class Outer {
public void show() {
// inner class of Class Outer
class Inner {
public void show() {
System.out.print(getClass().getName() + " inner in...");
System.out.println(getClass().getEnclosingClass());
}
}
System.out.print(getClass().getName() + " inner in...");
System.out.println(getClass().getEnclosingClass());
// inner class show() function
Inner i = new Inner();
i.show();
}
}
// outer class show() function
Outer o = new Outer();
o.show();
}
public static void main(String[] args) {
ClassDemo cls = new ClassDemo();
}
}
Выход
ClassDemo $1Outer внутри в классе ClassDemo
ClassDemo $1Outer $1Inner внутренний в... классе ClassDemo $1Outer
Ответ 6
Я искал поиски лучших ответов, чтобы узнать, что их нет.
Вот что я имею, что работает очень хорошо:
public static boolean isStatic(Class klass) {
return Modifier.isStatic(klass.getModifiers());
}
/**
* Non static inner class
*/
public static boolean isInnerclass(Class klass) {
return klass.getDeclaringClass() != null && !isStatic(klass);
}
Вернет true для локальных внутренних классов. isMemberClass и другие не работают для этой цели.