由CompilationUnit得到SuperClass的方法

做BTF项目的时候, 要判断一个类是否继承了某个指定类.

由于类还是在Eclipse的JDT中, 没有被Load, 所以java.lang.Class.getSuperclass()不中了.

查找一番原来可以通过CompilationUnit获取org.eclipse.jdt.core.IType,

然后IType.newSupertypeHierarchy(*)得到ITypeHierarchy, 继而就能用ITypeHierarchy.getSuperclass(IType)得到其超类了.

IType[] types = ((ICompilationUnit)javaElement).getTypes();
    if(null != types && types.length > 0){
         ITypeHierarchy typeHierarchy = types[0].newSupertypeHierarchy(null);
             IType superclass = typeHierarchy.getSuperclass(types[0]);
                if(superclass instanceof ResolvedBinaryType){
                 …

                  }
         }
}

永远不要在Java中使用String(至少也尽量少用:-)

永远不要使用(未封装)的String或long,int. 为什么呢? 因为这些基础类型(Primitive)没有语义(Semantic meaning). 它们很难被理解,维护和扩展.

空口无凭,举例为证: 假设有个例子是订阅电影票的服务.

试着比较:

public void bookTicket( String name, String firstName, String film, int count, String cinema);

与:(当然实际使用时,用一个Order对象会更好:-)

public void bookTicket( Name name, FirstName firstName, Film film, Count count, Cinema cinema);

很明显,第二个要容易阅读的多. 尤其是当在IDE中使用自动补全的时候,bookTicket(String arg0, String arg1, String arg2, int arg3, String arg4)bookTicket(Name arg0, FirstName arg1, Film arg2, Count arg3, Cinema arg4)差的太明显了.当某个接口被置于一个不带源码的jar包内时,这种情况很常见.

再尝试比较:

void book(String orderId);

与:

void book(OrderId order);

第一种情况下,开发人员看到这行代码会考虑:a.)怎样获得一个orderId 和b.)orderId到底是什么玩意, "1212", "ABC-123" or "12-34-45-SCHWEINEBACKE". 第二种情况,他可以去查看OrderId类的Javadoc或者使用手册获取它的正确用法. 或许觉得, 这不过是个orderId罢了. 但在遗留系统中,名称和语义是经常不一致的. 我曾经见过一个系统里面把order ID命名为"orderId", "auftragsId", "id"以及其他什么东西,而且居然指的是同一个东西: order ID!

多使用类替代基本类型不光有语义上的优势. 扩展上也更佳: 比如你可以更轻松的将OrderId类里的int替换成long, 增加校验和id生成逻辑. 相比而言,最初若使用String类型要做这些就困难的多.

使用fluent interface实现

fluent interface可以使代码更短,编写更容易. Google Collections的MapMaker是个不错的例子:

ConcurrentMap graphs = new MapMaker()
    .concurrencyLevel(32)
    .softKeys()
    .weakValues()
    .expiration(30, TimeUnit.MINUTES)
    .makeComputingMap(
        new Function() {
            public Graph apply(Key key) {
                return createExpensiveGraph(key);
            }
        });

使用fluent interface实现的如下所示,像简单的领域类(Domain classes)或者像不可变值的对象. 仅仅是封装了String并增加了一些语义的信息给String.

public class Name {
   public Name(String name) {
      ...
   }
   public static Name name(String name) {
     return new Name(name);
   }
}

有人或许觉得这种方式太过繁杂(noisy)了. 比如:

new Customer(new FirstName("Stephan"), new Name("Schmidt"));

要比如下的直接使用String参数的方式繁杂.

new Customer("Stephan", "Schmidt");

但,不可否认,第一个要更加容易理解, 若使用静态方法,第一个方法也可以变为:

new Customer(firstName("Stephan"), name("Schmidt"));

这样也较好的解决了参数较多时让人糊涂的问题.

[文章翻译自:http://codemonkeyism.com/never-never-never-use-string-in-java-or-at-least-less-often/ 请任意转载