从一个超类中获取一个子类的名字
比方说,我有一个名为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
关键字来轻松解决(例如: return this.class.getClass()
)。 但是,我需要这种方法保持静态。 有关如何解决这个问题的任何build议?
不可能。 静态方法不是运行时多态的。 区分这些情况是绝对不可能的:
System.out.println(Entity.getClass()); System.out.println(User.getClass());
它们编译成相同的字节码(假设该方法在Entity
定义)。
另外,你怎么称呼这个方法,使它具有多态性呢?
不要使方法静态。 问题是,当你调用getClass()
你正在调用超类的方法 – 静态方法不被inheritance。 另外,你基本上是名字遮蔽的Object.getClass()
,这是令人困惑的。
如果您需要在超类内logging类名,请使用
return this.getClass().getName();
这将返回“实体”,当你有一个Entity
实例,“用户”,当你有一个User
实例等
你的问题是不明确的,但据我可以告诉你想从静态方法知道当前类。 类相互inheritance的事实是不相干的,但为了讨论的缘故,我也是这样实现的。
class级家长{ public static void printClass(){ 的System.out.println(Thread.currentThread()的getStackTrace()[2] .getClassName()); } } 公共类testing扩展父{ public static void main(String [] args){ printClass(); } }
超类甚至不应该知道子类的存在,更不用说基于子类的全名来执行操作。 如果确实需要基于确切的类的操作,并且不能通过inheritance来执行必要的function,则应该沿着这些方向做些事情:
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; } }
(未经testing的代码)
这个类不知道它自己的子类,而是使用Class
类来执行操作。 最有可能的是,它仍然与实现紧密相连(通常是坏事,或者如果不坏,那就不是特别好 ),但是我认为像这样的结构比指示它的所有子类的超类更好。
你为什么要实现你自己的getClass()方法? 你可以使用
System.out.println(User.class);
编辑 (详细阐述一下):你想要的方法是静态的。 在这种情况下,你必须调用你想要的类名的类的方法,不pipe它是子类还是超级类。 然后,而不是调用MyClass.getClass()
,你可以调用MyClass.class
或MyClass.class.getName()
。
另外,您正在创build一个与Object.getClass()
实例方法具有相同签名的static
方法,该方法不会进行编译。
- 在超类中创build一个成员stringvariables。
- 将this.getClass()。getName()添加到将值存储在成员Stringvariables中的构造函数中。
- 创build一个getter来返回名称。
每次扩展类被实例化时,它的名字将被存储在string中并且可以被getter访问。
我有一些运气
this.getClass().asSubclass(this.getClass())
但我不知道它是如何工作的。
静态方法与类关联,而不是与特定的对象关联。
考虑如果有多个子类,这将如何工作 – 例如,pipe理员也是一个实体。 你的静态实体方法,只与实体类相关联,如何知道你想要哪个子类?
你可以:
- 使用现有的getClass()方法。
- 将parameter passing给您的静态getClass()方法,并在该对象上调用实例方法。
- 使您的方法非静态,并重命名它。
如果我正确理解你的问题,我认为你能达到你想要的唯一方法是在每个子类中重新实现静态方法,例如:
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.Dedived根据您的要求。 凌乱,但嘿,如果那些是你的约束…
如果我把它正确的你想在基类中使用你的子类在静态方法我认为你可以通过传递一个类参数的方法
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对象的子类。 我的解决scheme:在超类中创build一个类variables
Class<?> claz;
然后在子类中,我会在构造函数中设置超类的variables
public class SubClass { public SubClass() { claz = this.getClass(); } }
这是很简单的做的
User.getClass()。getSuperclass之()