Подтвердить что ты не робот

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
4b9b3361

Ответ 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 и другие не работают для этой цели.