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

Получение имени подкласса из суперкласса

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

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

Теперь у меня есть еще один класс.

class User extends Entity {
}

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

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

Моя цель - увидеть вывод "com.packagename.User" на консоль, но вместо этого я вернусь к "com.packagename.Entity", поскольку на класс Entity ссылаются непосредственно из статического метода.

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

return this.getClass().getName();

Это приведет к возврату "Entity", если у вас есть экземпляр Entity, "Пользователь", когда у вас есть экземпляр User и т.д.

Ответ 3

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

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();
    }
}

Ответ 4

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

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 для выполнения операций. Скорее всего, он все равно будет тесно связан с реализациями (как правило, это плохо, или, если не плохо, это не особенно хорошо), но я думаю, что такая структура лучше, чем суперкласс, выясняя, что все его подклассы.

Ответ 5

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

System.out.println(User.class);

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

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

Ответ 6

Мне повезло с

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

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

Ответ 7

  • Создать элемент Строковая переменная в суперклассе.
  • Добавьте this.getClass(). getName() в конструктор, который сохраняет значение в переменной String элемента.
  • Создайте getter, чтобы вернуть имя.

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

Ответ 8

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

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

Вы можете:

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

Ответ 9

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

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

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

Это будет печатать package.Entity и package.Derived по мере необходимости. Грустно, но эй, если это ваши ограничения...

Ответ 10

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

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);
    }
}

Ответ 11

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

Class<?> claz;

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

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

Ответ 12

это очень просто сделать с помощью

User.getClass(). GetSuperclass()