gpt4 book ai didi

java - Java ME 上的 Class.getSuperclass() 替代品?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:42:05 25 4
gpt4 key购买 nike

如何在 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

并将 AC 添加到树中,并向它询问 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com