假設我有這些課程:
public class ChildClass extends ParentClass
{
// some class definition here
}
public abstract class ParentClass
{
public static void printClass()
{
// get the class that extends this one (and for example, print it)
}
// some class definition here
}
可以說,在呼叫時ParentClass.printClass()我想列印類的名稱(例如 do System.out.println(ParentClass.class))。當然后擴展ParentClass(例如像 in ChildClass)和呼叫ChildClass.printClass()時,我希望它列印擴展類的名稱(像 do System.out.println(ChildClass.class))。這有可能嗎?
我找到了一種通過使用從靜態方法內部獲取類的方法MethodHandles.lookup().lookupClass(),但是當在內部使用它ParentClass.printClass并擴展 ParentClass,然后呼叫printClass擴展類時,我總是得到ParentClass.
uj5u.com熱心網友回復:
最好將靜態方法視為完全存在于類本身之外。它們出現在類中的原因是因為 java(語言)本身的設計:型別不僅僅是具有層次結構的型別,它們也是 java 命名空間系統的主要載體。
型別存在于包中,包是型別的頂級命名空間概念。那么如何參考一個方法呢?只有一種方法:通過型別系統。因此,靜態方法必須放在型別中。但這就是它結束的地方。
他們根本不繼承。當你寫:
ChildClass.lookupClass()
編譯器只是弄清楚:對,好吧,您顯然指的是lookupClass()方法,ParentClass所以這就是我要編譯的。您可以通過運行親自看到這一點javap -c -p MyExample。同樣的原則也適用于非靜態方法。
對于實體方法,運行時取消了這個操作:每當您在任何物件上呼叫方法時,運行時系統將始終執行動態調度;你不能選擇退出這個。你可以寫:
AbstractList<String> list = new ArrayList<String>();
list.sort(someComparator);
and you can use javap to verify that this will end up writing into the class file that the method AbstractList::sort is invoked. But, at runtime the JVM will always check what list is actually pointing at - it's an instance of ArrayList, not AbstractList (that's obvious: AbstractList is abstract; no object can ever be directly instantiated as `new AbstractList). If ArrayList has its own take on the sort method, then that will be called.
The key takeaway of all that is: Static methods do not inherit, therefore, this dynamic dispatch system is not available to them, therefore, what you want cannot be done in that fashion.
So what to do?
It feels like what you're doing is attempting to associate a hierarchy to properties that apply to the class itself. In other words, that you want there to be a hierarchical relationship between the notion of 'ParentClass's lookupClass method and ChildClass's lookupClass method - lookupClass is not a thing you ask an instance of ChildClass or ParentClass - you ask it at the notion of the these types themselves.
If you think about it for a moment, constructors are the same way. You don't 'ask' an instance of ArrayList for a new arraylist. You ask ArrayList, the concept. Both 'do not really do' inheritance and cannot be abstracted into a type hierarchy.
This is where factory classes come in.
Factory classes as a concept are just 'hierarchicalizing' staticness, by removing static from it: Create a sibling type to your class hierarchy (ParentClassFactory for example):
abstract class ParentClassFactory {
abstract ParentClass create();
abstract void printClass();
}
and then, in tandem with writing ChildClass, you also write ChildClassFactory. Generally factories have just one instance - you may want to employ the singleton pattern for this. Now you can do it just fine:
class ChildClassFactory extends ParentClassFactory {
private static final ChildClassFactory INSTANCE = new ChildClassFactory();
public static ChildClassFactory instance() { return INSTANCE; }
public ParentClass create() { return new ChildClass(); }
public void printClass() { System.out.println(ChildClass.class); }
}
// elsewhere:
// actually gets the ChildClassFactory singleton:
ParentClassFactory factory = ....;
factory.printClass(); // will print ChildClass!
uj5u.com熱心網友回復:
Quoting @RealSkeptic:
Static methods are not inherited. The fact that you can call ChildClass.printClass() is just syntactic sugar. It actually always calls ParentClass.printClass(). So you can't do something like that with a static method, only an inheritable non-static one.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/463841.html
