- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
如何在 Java ME 中获取 Class 实例的父类(super class)。也就是说,用 CLDC 1.1 中可用的有限功能伪造 Class.getSuperclass() 功能?
我想做的是让抽象父类(super class)做这样的事情:
public Styler getStylerForViewClass(Class clazz) {
Styler s = stylers.get(clazz);
if (s == null) {
for (Class c = clazz; s == null; c = c.getSuperclass()) {
if (c == Object.class) {
throw new IllegalArgumentException("No Styler for " + clazz.getName());
}
s = createStylerForViewClass(c);
}
stylers.put(clazz, s);
}
return s;
}
public Styler createStylerForViewClass(Clazz clazz) {
if (clazz == View.class) {
return new DefaultStyler();
} else {
return null;
}
}
然后子类可以像这样添加特化:
public Styler createStylerForViewClass(Class clazz) {
if (clazz == SpecialView.class) {
return new SpecialStyler();
} else {
return super.createSylerForViewClass(clazz);
}
}
最佳答案
正如您已经发现的那样,MIDP 不提供获取类的父类(super class)的方法,也不提供枚举应用程序中所有类的方法。
所以您所能做的就是自己跟踪类层次结构。
拥有一个公共(public)父类(super class)会稍微容易一些,因为您可以让新对象在父类(super class)构造函数中将其自己的类添加到全局类集合(如果尚未存在):
abstract class View {
protected View() {
classHierarchy.add(this.getClass());
}
}
但不幸的是,这不适用于抽象类,因为从未创建任何实例。
跟踪已知类子集的父类(super class)/子类关系非常容易。例如:
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;
}
但这可能会“错过”稍后添加的中间类,例如如果你有这些类(class):
Object >= View >= A >= B >= C
并将 A
和 C
添加到树中,并向它询问 C
的父类(super class),它会给你 A
,如果您稍后添加 B
,它将取代 A
作为 C
的父类(super class),但直到返回了错误的样式器C
的一些实例。
因此我认为您必须添加限制,即必须首先将祖先类(已为其定义样式器)添加到树中。可能来自覆盖 createStylerForViewClass
的类的静态初始化程序 block ,或者来自 View 类本身的静态初始化程序。
我确实想到了另一个邪恶的黑客,但我真的不能推荐它:
View
构造函数中,创建一个新的 Exception
,但不要抛出它。System.err
换成您自己写入 ByteArrayOutputStream
的编写器printStackTrace()
System.err
恢复到原来的值ByteArrayOutputStream
解析堆栈跟踪。中间类的构造函数的名称将在堆栈跟踪中。现在您可以使用 Class.forName()
查找它们并将它们添加到树中。关于java - Java ME 上的 Class.getSuperclass() 替代品?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2102280/
我是一名优秀的程序员,十分优秀!