我如何可以获得超类中的一类实例中Java我。那是假的类。getSuperclass()功能与功能有限的可用于CLDC1.1?

我想要做的就是让抽象超级这样做:

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);
   }
 }
有帮助吗?

解决方案

因为你已经发现,使不能提供一种用于获得超类中的一类,也没有为列举的所有类的应用程序。

因此,所有你可以做的是跟踪类层次的自己。

具有一个共同的超类使它稍微容易,因为你可以有新的对象添加自己的类的一个全球性的类收集(如果不是已经存在)超类的构造:

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

和add AC 到树,并要求它对超类的 C 它会给你 A,如果你以后加入 B 它将取代 A 作为超类的 C, 但直到错误的斯泰勒已经返回的一些实例 C.

所以我想你会需要添加的限制类的祖先(于有造型器定义为他们)必须加入树第一次。可能从静态的初始化框类的复盖 createStylerForViewClass, 或静态的初始化的看类本身。

我认为一个人的其他邪恶的黑客,但是我真的不能建议:

  • View 构造,创建一个新的 Exception, 但不要扔掉它。
  • 暂时换 System.err 为自己的作家,写入一个 ByteArrayOutputStream
  • 呼叫 printStackTrace() 在例外
  • 恢复 System.err 其原有的价值
  • 分析堆跟踪从 ByteArrayOutputStream.该名中间类的构造,将在栈踪。现在你可以看看他们使用 Class.forName() 并把它们添加到树。

其他提示

您有两种选择:

如果你知道超类属于一组有限的,你可以叫的instanceof或使用的 Class.isInstance()方法。

可替换地,可以有一个预处理器对您的代码运行,并创建一个单独保存的数据结构,其保持你的类的信息。甚至可能是一个自定义的的doclet CAN做到这一点。输出可以是描述的结构的文本或二进制文件:

 ClassA:SuperClass
 ClassB:AnotherSuperClass
 etc.

注意您可能有问题,在这种方式的混淆。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top