我从未使用过类型别名,但是这个概念似乎是一个非常有用的功能,它可以在相同类型的对象上添加语义并防止常见的拼写错误。
我们说,有void foo(float volume, float weight)
。如果它被调用的话可以这样做:foo(v, m)
,但foo(m, v)
不是一个明显的拼写错误。 void process(Iterable<File> javaPath, Iterable<File> classPath)
可以是另一个用例。不幸的是,Java中没有类型别名,并且一些解决方法是真正的过度杀伤:
因此,它们都有缺点和运行时间/性能成本。
据我所知,在Java中,基于运行时的&#34;类型别名&#34;可能会被编译时检查所取代,例如@NotNull和@Nullable被处理。是否有任何静态类型别名检查器/ APT工具支持void foo(@Volume float volume, @Weight float weight)
之类的结构,以便检查器可以验证这样的&#34;类型安全&#34;在编译时,需要传递变量/常量和文字进行注释(分别在声明和调用站点)?
这个问题也有人提出,因为我目前正在研究一种可以使用多个后端的Java源代码处理工具(目前只有JDT)。只要我希望它与JDT无关,我想拥有类型,方法和字段的业务对象。尽管如此,我丢失了大量来自JDT AST的信息,我工具当前最好的方法是使用字符串(它允许执行一些对工具范围足够的分析)。但是像void process(String type, String field, String method)
这样的方法令人困惑,因此我创建了代表域对象的Type
,Field
和Method
,并且与JDT无关。它们很好,但我不希望将来扩展它们(所有这三种类型都有单private final String name;
字段+我必须覆盖hashCode/equals
和{{1 }})。这让我想到再次对APT进行类型检查。只要处理原始数据是可以的,只需toString
(我仍然可以使用单个对象)就足够了。
答案 0 :(得分:0)
如果您的问题是,当您致电foo(v,m)
时,人们可能会在没有任何警告或可见的错误线索的情况下错误地写foo(m,v)
时看起来很模糊,您可以使用类似流利的建设者模式:
(代码未经过测试,只是为了证明这个想法而编写)
public class MyClass {
public class FooStub {
int volume;
int weight;
public FooStub withVolume(int v) {
this.volume = v;
return this;
}
public FooStub withWeight(int w) {
this.weight = w;
return this;
}
public int run() { // or call it getResult() or whatever you want
Assert.notNull(volume);
Assert.notNull(weight);
return foo(volume,weight); // calling method of outer class
}
}
public int foo(int volume, int weight) { // you even hide this if you want
return volume * weight;
}
public FooStub foo() {
return new FooStub();
}
}
通过这样做,来电者可以
MyClass myObj = ....;
int result = myObj.foo().withVolume(a).withWeight(b).run();
// which is the same as result = myObject.foo(a,b);