正如您已经发现的那样,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