Получив название суб-класса из супер-класса


Допустим, у меня есть базовый класс с именем Entity. В этом классе у меня есть статический метод для получения имени класса:

class Entity {
    public static String getClass() {
        return Entity.class.getClass();
    }
}

теперь у меня есть другой класс расширить это.

class User extends Entity {
}

Я хочу получить имя класса пользователей:

System.out.println(User.getClass());

моя цель-увидеть " com.имя пакета.Пользователь " вывод на консоль, но вместо этого я собираюсь закончить с "com.имя пакета.Сущность " так как на класс сущности ссылаются непосредственно из статического метод.

если бы это не был статический метод, это можно было бы легко решить с помощью this сайта в Entity класса (т. е.: return this.class.getClass()). Однако, мне нужен этот метод, чтобы оставаться статичными. Любые предложения о том, как подойти к этому?

12 58

12 ответов:

не возможно. Статические методы никоим образом не являются полиморфными во время выполнения. Совершенно невозможно различить эти случаи:

System.out.println(Entity.getClass());
System.out.println(User.getClass());

они компилируются в один и тот же байтовый код (при условии, что метод определен в Entity).

кроме того, как бы вы назвали этот метод таким образом, чтобы он имел смысл быть полиморфным?

не делайте метод статическим. Проблема в том, что при вызове getClass() вы вызываете метод в суперклассе-статические методы не наследуются. Кроме того, вы в основном имя-затенение Object.getClass(), что сбивает с толку.

Если вам нужно зарегистрировать имя класса в суперклассе, используйте

return this.getClass().getName();

это вернет "сущность", когда у вас есть Entity экземпляра, "пользователь", когда у вас есть User экземпляр, etc.

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

class Parent {
    public static void printClass() {
      System.out.println(Thread.currentThread().getStackTrace()[2].getClassName());
    }
}

public class Test extends Parent {
    public static void main(String[] args) {
      printClass();
    }
}

это работает для меня

this.getClass().asSubclass(this.getClass())

но я не уверен, как это работает.

public class MyClassUtil
{
    public static String doWorkBasedOnClass(Class<?> clazz)
    {
        if(clazz == MyNormalClass.class)
        {
            // Stuff with MyNormalClass
            // Will not work for subclasses of MyNormalClass
        }

        if(isSubclassOf(clazz, MyNormalSuperclass.class))
        {
            // Stuff with MyNormalSuperclass or any subclasses
        }

        // Similar code for interface implementations
    }

    private static boolean isSubclassOf(Class<?> subclass, Class<?> superclass)
    {
        if(subclass == superclass || superclass == Object.class) return true;

        while(subclass != superclass && subclass != Object.class)
        {
            subclass = subclass.getSuperclass();
        }
        return false;
    }
}

(непроверенного кода)

этот класс также не знает о своих собственных подклассах, а скорее использует Class класс для выполнения операций. Скорее всего, он все равно будет тесно связан с реализациями (как правило, плохо, или если не плохо, это не особенно хороший), но я думаю, что такая структура лучше, чем суперкласс выяснить, что все его подклассы.

почему вы хотите реализовать свой собственный метод getClass ()? Вы можете просто использовать

System.out.println(User.class);

Edit (чтобы немного уточнить): вы хотите, чтобы метод был статическим. В этом случае вы должны вызвать метод для класса, имя которого вы хотите, будь то подкласс или суперкласс. Тогда вместо вызова MyClass.getClass(), вы можете просто позвонить MyClass.class или MyClass.class.getName().

кроме того, вы создаете static метод с той же сигнатурой, что и Object.getClass() метод экземпляра , который не будет компилироваться.

  1. создать строковую переменную-член в суперклассе.
  2. добавить этого.getClass().getName () к конструктору, который хранит значение в переменной строки-члена.
  3. создайте геттер для возврата имени.

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

статический метод связан с классом, а не с конкретным объектом.

рассмотрим, как это будет работать, если бы было несколько подклассов-например, администратор также является сущностью. Как бы ваш статический метод сущности, связанный только с классом сущности, знал, какой подкласс вы хотите?

вы можете:

  • используйте существующий метод getClass ().
  • передайте аргумент в статический метод getClass () и вызовите метод экземпляра на этом объекте.
  • сделайте свой метод нестатическим и переименуйте его.

Если я правильно понимаю ваш вопрос, я думаю, что единственный способ достичь того, что вы хотите,-это повторно реализовать статический метод в каждом подклассе, например:

class Entity {
    public static String getMyClass() {
        return Entity.class.getName();
    }
}

class Derived extends Entity {
    public static String getMyClass() {
        return Derived.class.getName();
    }
}

это будет печатать пакет.Сущность и пакет.Производные, как вам требуется. Грязно, но эй, если это ваши ограничения...

Если я правильно понимаю, вы хотите использовать свой подкласс в базовом классе в статическом методе Я думаю, что вы можете сделать, передав параметр класса в метод

class Entity {
    public static void useClass(Class c) {
        System.out.println(c);
        // to do code here
    }
}

class User extends Entity {
}

class main{
    public static void main(String[] args){
        Entity.useClass(Entity.class);
    }
}

мой контекст: сущность суперкласса с подклассами для объектов XML. Мое решение: Создайте переменную класса в суперклассе

Class<?> claz;

тогда в подклассе я бы установил переменную суперкласса в конструкторе

public class SubClass {
   public SubClass() {
     claz = this.getClass();
   }
}

Это очень просто сделать

пользователей.getClass().getSuperclass()