Java ME 上的 Class.getSuperclass() 替代品?
如何获取 Java ME 中 Class 实例的超类。也就是说,用 CLDC 1.1 中可用的有限功能来伪造 Class.getSuperclass() 功能?
我想做的是让抽象超类做这样的事情:
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);
}
}
How can I get the the superclass of a Class instance in Java ME. That is, fake the Class.getSuperclass() functionality with the limited functionality available in CLDC 1.1?
What I want to do is to let the abstract super class do something like this:
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;
}
}
Sub classes could then add specializations like this:
public Styler createStylerForViewClass(Class clazz) {
if (clazz == SpecialView.class) {
return new SpecialStyler();
} else {
return super.createSylerForViewClass(clazz);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如您已经发现的,MIDP 不提供获取类的超类的方法,也不提供枚举应用程序中所有类的方法。
因此,您所能做的就是自己跟踪类层次结构。
拥有一个公共超类会使事情变得稍微容易一些,因为您可以让新对象将其自己的类添加到超类构造函数中的全局类集合(如果尚未存在)中:
但不幸的是,这不适用于抽象类,因为没有实例曾经创造过。
跟踪已知类子集的超类/子类关系非常容易。例如:
但这可能会“错过”稍后添加的中间类,例如,如果您有这些类:
并将
A
和C
添加到树中并询问其超类C
的它会给你A
,如果你后来添加B
它将取代A
作为C
,但直到为C
的某些实例返回错误的样式器为止。因此,我认为您必须添加以下限制:必须首先将祖先类(为其定义了样式器)添加到树中。可能来自覆盖
createStylerForViewClass
的类的静态初始化程序块,或视图类本身的静态初始化程序。我确实想到了另一种邪恶的黑客,但我真的不能推荐它:
View
构造函数中,创建一个新的Exception
,但不要抛出它。System.err
替换为您自己的编写器,写入ByteArrayOutputStream
printStackTrace()
System.err< /code> 为其原始值
ByteArrayOutputStream
的堆栈跟踪。中间类的构造函数的名称将出现在堆栈跟踪中。现在您可以使用 Class.forName() 查找它们并将它们添加到树中。As you have already discovered, MIDP does not provide a method for getting the superclass of a class, nor for enumerating all classes in the application.
So all you can do is keep track of the class hierarchy yourself.
Having a common superclass makes it slightly easier, because you can have the new object add its own class to a global class collection (if not already present) in the superclass constructor:
but unfortunately this will not work for abstract classes, because no instances are ever created.
Keeping track of superclass/subclass relations for a known subset of classes is easy enough. e.g.:
But this can "miss" intermediate classes that are added later, e.g. if you have these classes:
and add
A
andC
to the tree and asked it for the superclass ofC
it would give youA
, and if you later addedB
it would replaceA
as the superclass ofC
, but not until the wrong styler had been returned for some instances ofC
.So I think you will have to add the restriction that ancestor classes (that have stylers defined for them) must be added to the tree first. Possibly from the static initializer block of the class that overrides
createStylerForViewClass
, or the static initializer of the view class itself.I did think of one other evil hack, but I can't really recommend it:
View
constructor, create a newException
, but don't throw it.System.err
for your own writer that writes to aByteArrayOutputStream
printStackTrace()
on the exceptionSystem.err
to its original valueByteArrayOutputStream
. The names of the intermediate classes' constructors will be in the stack trace. Now you can look them up usingClass.forName()
and add them to the tree.您有两个选择:
如果您知道超类属于有限集,则可以仅调用instanceof或使用Class.isInstance() 方法。
或者,您可以让一个预处理器在您的代码上运行,并创建一个单独保存的数据结构,用于保存您的类信息。甚至可能自定义 doclet 也可以做吧。输出可以是描述结构的文本或二进制文件:
请注意,您可能会遇到这种方式的混淆问题。
You have two options:
If you know that the super class belongs to a limited set, you can just call instanceof or use the Class.isInstance() method.
Alternatively, you can have a preprocessor to run on you code and create a data structure that is saved separately which holds your classes information. Probably even a custom doclet can do it. The output can be a text or binary file that describes the structure:
Notice you may have problem with the obfuscation in this way.