Получив название суб-класса из супер-класса
Допустим, у меня есть базовый класс с именем 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 ответов:
не возможно. Статические методы никоим образом не являются полиморфными во время выполнения. Совершенно невозможно различить эти случаи:
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(); } }
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()
метод экземпляра , который не будет компилироваться.
- создать строковую переменную-член в суперклассе.
- добавить этого.getClass().getName () к конструктору, который хранит значение в переменной строки-члена.
- создайте геттер для возврата имени.
каждый раз, когда создается экземпляр расширенного класса, его имя будет сохранено в строке и доступно с помощью геттера.
статический метод связан с классом, а не с конкретным объектом.
рассмотрим, как это будет работать, если бы было несколько подклассов-например, администратор также является сущностью. Как бы ваш статический метод сущности, связанный только с классом сущности, знал, какой подкласс вы хотите?
вы можете:
- используйте существующий метод 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); } }