我想为字符串提供Kotlin扩展功能,该功能只能在MyParent
类的继承者中访问(受保护的功能)。 MyParent
类是用Java编写的,不能转换为Kotlin。是否可以在Java代码中定义一个可用作Kotlin代码扩展功能的方法?
我想我期望某种适当的签名,或者一些神奇的@ThisIsExtenstionFunction批注。
答案 0 :(得分:2)
实际上,您可以。非开箱即用,但有可能;)
让我们考虑这个例子。
首先,用Java创建一个类MyParent
public class MyParent {
}
然后,在此界面中定义扩展方法:
interface MyParentExt {
fun String.ext(importantParam: Int)
}
因此,让MyParent
实现此接口。
public class MyParent implements MyParentExt {
@NonNull
@Override
public String ext(@NonNull String $receiver, int importantParam) {
// do cool stuff
return $receiver;
}
// For testing let's add other public method:
public String ext(int importantParam) {
return "Kotlin > Java";
}
}
所以,让我们检查一下我们可以在孩子身上做什么:
// Java child:
public class MyJavaChild extends MyParent {
MyJavaChild() {
"Java xD".ext(0); // Invalid! There is no such a method!
ext("Java xD", 0); // Valid call for extension function
ext(0); // Just Valid ;)
}
}
// Kotlin class:
class MyGreatKotlinChild : MyParent() {
init {
"Kotlin is cool".ext(0) // Valid extension function!
ext("Kotlin is cool", 0) // Invalid call. There is no method with such a signature!
ext(0) // Valid.
}
}
因此,我们可以使用lang指定的符号同时访问Java和Kotlin中的扩展方法。
作为您的要求之一,您希望保护此方法。 不幸的是,接口方法的可见性始终是公开的。因此,您仍然应该能够在成员上调用此函数。
但是...让我们检查一下它实际上是如何工作的;)
// Java
public class Test {
public static void main(String[] args) {
MyChild child = new MyChild();
// Both methods are valid
child.ext("Java...", 0);
child.ext(0);
}
}
// Kotlin
fun main() {
child.ext(0) // Normal function, valid call.
child.ext("It actually works...", 0) // Hah, no way ;)
// Just to be sure:
"String".ext(0) // Nope, this ext method is visible for only class scope.
}
此外,您的父类只能扩展ParentOfMyParent
类,您可以在其中定义扩展方法:
// Kotlin
abstract class ParentOfMyParent {
protected abstract fun String.ext()
}
// Java
public class Parent extends ParentOfMyParent {
@Override
protected void ext(@NotNull String $receiver) {
}
}
// Kotlin-child
class Child : Parent() {
init {
"".ext()
}
}
// Java-child
public class ChildJava extends Parent {
ChildJava() {
ext("");
}
}
这种方法具有所需的可见性。
答案 1 :(得分:0)
没有这样的注释。
但是,编译器会发出可能包含此信息的kotlin元数据注释,但是j建议不要尝试诱使编译器认为某个类是kotlin源而不是java源。 更多信息:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-metadata/index.html