在Kotlin中,以下代码编译:
class Foo {
fun bar(foo: List<String>): String {
return ""
}
fun bar(foo: List<Int>): Int {
return 2;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,此代码不会:
class Foo {
fun bar(foo: List<String>): String {
return ""
}
fun bar(foo: List<Int>): String {
return "2";
}
}
Run Code Online (Sandbox Code Playgroud)
编译它会导致以下错误:
Error:(8, 5) Kotlin: Platform declaration clash: The following declarations have the same JVM signature (foo(Ljava/util/List;)Ljava/lang/String;):
fun foo(layout: List<Int>): String
fun foo(layout: List<String>): String
Run Code Online (Sandbox Code Playgroud)
在Java中,两个示例都不会编译:
class Foo {
String bar(List<Integer> foo) {
return "";
}
Integer bar(List<String> foo) …Run Code Online (Sandbox Code Playgroud) 以下声明在Kotlin中是合法的.
fun foo(): String = "foo_1"
fun <T> foo(): T = "foo_2" as T
Run Code Online (Sandbox Code Playgroud)
作为字节码我们得到:
public final static foo()Ljava/lang/String;
// signature <T:Ljava/lang/Object;>()TT;
// declaration: T foo<T>()
public final static foo()Ljava/lang/Object;
Run Code Online (Sandbox Code Playgroud)
也可以从Kotlin调用这两种方法.
当我试图从Java中调用其中任何一个时,问题出现了:
ClassKt.foo()
Run Code Online (Sandbox Code Playgroud)
暧昧的电话.两种方法都匹配......
如何避免这样的问题?如何处理这样的方法?如果第三方kt库有同样的问题怎么办?
上面的例子是合成的例子.
我正在尝试在JBoss AS6上的后端服务中使用CDI事件 - 理想情况下是最大程度地重用代码.
我可以从文档中看到我可以通过使用带有成员的限定符来减少必须创建的限定符注释类.
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Type {
TypeEnum value();
}
Run Code Online (Sandbox Code Playgroud)
我可以观察到这一点
public void onTypeAEvent(@Observes @Type(TypeEnum.TYPEA) String eventMsg) {...}
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是,为了进一步减少所需类的数量,我希望有一个EventFirer类,其中抛出的事件的限定符是动态的.没有成员的限定符没有问题:
public class DynamicEventFirer {
@Inject @Any private Event<String> event;
public void fireEvent(AnnotationLiteral<?> eventQualifier){
event.select(eventQualifier).fire("FIRED");
}
}
Run Code Online (Sandbox Code Playgroud)
然后叫做喜欢
dynamicEventFirer.fireEvent(new AnnotationLiteral<Type>() {});
Run Code Online (Sandbox Code Playgroud)
但是,当资格赛成员应该有成员时呢?查看AnnotationLiteral的代码,它肯定是为成员设置的,而class元素注释具有以下示例:
new PayByQualifier() { public PaymentMethod value() { return CHEQUE; } }
Run Code Online (Sandbox Code Playgroud)
这对我来说很有意义 - 你要覆盖注释界面的value()方法.但是,当我自己尝试这个时:
dynamicEventFirer.fireEvent(new AnnotationLiteral<Type>() {
public TypeEnum value() {
return TypeEnum.TYPEA;
}
});
Run Code Online (Sandbox Code Playgroud)
我收到了例外
java.lang.RuntimeException: class uk.co.jam.concept.events.MemberQualifierEventManager$1 does not implement …Run Code Online (Sandbox Code Playgroud)