正如您已經發現的那樣,MIDP不提供獲取類的超類的方法,也不提供用於枚舉應用程序中的所有類的方法。
所以你所能做的就是自己跟蹤類層次結構。
擁有一個共同的超使它稍微容易些,因爲你可以有新的對象添加自己的類全局類集合(如果尚未存在)在超類的構造函數:
abstract class View {
protected View() {
classHierarchy.add(this.getClass());
}
}
,但不幸的是這將不適用於抽象類,因爲沒有創建任何實例。
跟蹤一個已知子類的超類/子類關係很容易。例如爲:
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
public class ClassHierarchy {
public ClassHierarchy() {
childToParentMap = new Hashtable();
parentToChildMap = new Hashtable();
parentToChildMap.put(Object.class, new Vector());
}
public boolean addClass(Class toAdd) {
if (toAdd.isInterface()) return false;
if (toAdd.equals(Object.class)) return false;
if (childToParentMap.get(toAdd) != null) return false;
addClassBelow(toAdd, Object.class, new Vector());
return true;
}
public Class getParent(Class subclass) {
return (Class) childToParentMap.get(subclass);
}
private void addClassBelow(Class toAdd, Class parent, Vector initialChildren) {
Vector children = (Vector) parentToChildMap.get(parent);
Class reparented;
do {
reparented = null;
for (Enumeration childEnum = children.elements();
childEnum.hasMoreElements();
) {
Class child = (Class) childEnum.nextElement();
if (child.isAssignableFrom(toAdd)) {
addClassBelow(toAdd, child, initialChildren);
return;
} else if (toAdd.isAssignableFrom(child)) {
children.removeElement(child);
initialChildren.addElement(child);
childToParentMap.put(child, toAdd);
// Guard against concurrent modification
reparented = child;
break;
}
}
} while (reparented != null);
children.addElement(toAdd);
childToParentMap.put(toAdd, parent);
parentToChildMap.put(toAdd, initialChildren);
}
private Hashtable childToParentMap;
private Hashtable parentToChildMap;
}
但是,這可以「錯過」以後添加中間類,例如如果你有這些類:
Object >= View >= A >= B >= C
,並添加A
和C
樹,並要求其爲C
超它會給你A
,如果你後來添加B
它將取代A
爲C
超,但是直到錯誤的樣式文件返回了C
的某些實例。
所以我認爲你必須添加限制,祖先類(它們爲其定義的樣式)必須首先添加到樹中。可能來自覆蓋createStylerForViewClass
的類的靜態初始化器塊,或者視圖類本身的靜態初始化器。
我沒想到一個其他邪惡的黑客,但我真的不能推薦一下:
- 在
View
構造函數中,創建一個新的Exception
,但不要把它。
- 暫時交換
System.err
爲自己的作家寫入到ByteArrayOutputStream
- 呼叫
printStackTrace()
異常
- 上恢復
System.err
其原始值
- 解析從
ByteArrayOutputStream
堆棧跟蹤。中間類的構造函數的名稱將在堆棧跟蹤中。現在你可以使用Class.forName()
來查找它們並將它們添加到樹中。
是否有所有視圖類的通用超?這些方法('createStylerForViewClass'和'getStylerForViewClass')是否屬於那個超類?如果是這樣,那麼爲什麼需要'clazz'參數? – finnw
是的,他們有一個共同的超類,但你不會實現這些方法。只需使用自己的類調用getStylerForViewClass()以獲得最適合他們的樣式器。 – PeyloW