在 Kotlin 中使用静态 Java 方法作为静态(或单例)属性
use static Java methods as static (or singleton) properties in Kotlin
我的 SDK 暴露了一个只有静态方法的 Java 接口,例如
public interface MyDevice {
public static void setLocation(Location location) {…}
public static Location getLocation() {…}
}
在使用 SDK 的 Java 应用程序中,我的客户可以使用这些 就好像 它是一个单例,例如
Location currentLocation = MyDevice.getLocation();
当此 SDK 集成到 Kotlin 应用程序中时,很自然地表示与 属性 相同:
val currentLocation = MyDevice.location
问题是,此内置互操作仅适用于非静态方法。
我可以在 Kotlin 中创建一个单例并让它处理翻译:
object myDevice {
var location: Location
get() = MyDevice.getLocation()
set(location) = MyDevice.setLocation(location)
}
但是,在其他 Java-only SDK 中,这个单一的 Kotlin 文件不会对不使用 Kotlin 的客户产生负面影响吗?同样可以用Java来表达吗?
或者我应该简单地将 MyDevice.java 转换为 Kotlin?此步骤对仍在使用 Java 的客户有何负面影响?
在 Kotlin 中,为了获得与 Java 接口中的静态方法相同的结果,您应该使用 companion object
来声明您的静态方法。示例:
interface MyDevice {
// instance methods
companion object {
// static methods
@JvmStatic
fun setLocation(location: Location) {...}
@JvmStatic
fun getLocation(): Location {...}
}
}
注意 @JvmStatic
注释。当您从 Java class 调用这些 Kotlin 函数时,它们将被解释为静态方法。示例:
public void myJavaMethod() {
Location location = MyDevice.getLocation();
}
您描述的问题是缺少元数据 Kotlin 需要将静态方法视为 Class 扩展函数的扩展属性。
连同问题KT-11968,至少目前无法实现。
最好的选择是 API 转换为 Kotlin,并在必要时支持 @JvmStaic/@JvmField 和 @JvmDefault 以实现向后兼容性。
interface MyDevice {
companion object {
// nullable type or explicit init
var location: Location?
@JvmStatic get
@JvmStatic set
// kotlin
val x = MyDevice.location
MyDevice.location = x
// java
var x = MyDevice.getLocation();
MyDevice.setLocation(x);
kotlin lang 提供的解决方案很少,我们可以使用这些解决方案来简化您的案例。在 Java 之间做出更好的工作是 kotlin 的本质,对我来说,我没有看到使用 Companion/Object 创建类似于 Java 的静态方法有任何缺点。为了简单起见,kotlin 语言本身也为开发人员提供了许多方便的帮助程序。以下是我们可以申请的:
- 对象
object MyDevice {
@JvmStatic
fun getLocation(): Location {
}
@JvmStatic
fun setLocation(location: Location) {
}
}
- 同伴
class MyDevice {
companion object {
@JvmStatic
fun getLocation(): Location {
}
@JvmStatic
fun setLocation(location: Location) {
}
}
}
来电Java:
MyDevice.setLocation(location);
final Location location = MyDevice.getLocation();
阅读了专家的回答,研究了他们提供的链接,反编译了包装器的 Kotlin 代码 class 并分析了一个演示应用程序(纯 Java) Kotlin-wrapped 库,我决定更改 Java API.
现在我有一个 class 和一个 public 静态对象:
public class MyDevice {
public static MyDevice myDevice;
public void setLocation(Location location) {…}
public Location getLocation() {…}
}
现在 Java 消费者将使用
import static com.example.sdk.MyDevice.myDevice;
Kotlin 消费者不需要 static:
import com.example.sdk.MyDevice.myDevice
所以,我的库不需要单独的 Kotlin 风格!
我的 SDK 暴露了一个只有静态方法的 Java 接口,例如
public interface MyDevice {
public static void setLocation(Location location) {…}
public static Location getLocation() {…}
}
在使用 SDK 的 Java 应用程序中,我的客户可以使用这些 就好像 它是一个单例,例如
Location currentLocation = MyDevice.getLocation();
当此 SDK 集成到 Kotlin 应用程序中时,很自然地表示与 属性 相同:
val currentLocation = MyDevice.location
问题是,此内置互操作仅适用于非静态方法。
我可以在 Kotlin 中创建一个单例并让它处理翻译:
object myDevice {
var location: Location
get() = MyDevice.getLocation()
set(location) = MyDevice.setLocation(location)
}
但是,在其他 Java-only SDK 中,这个单一的 Kotlin 文件不会对不使用 Kotlin 的客户产生负面影响吗?同样可以用Java来表达吗?
或者我应该简单地将 MyDevice.java 转换为 Kotlin?此步骤对仍在使用 Java 的客户有何负面影响?
在 Kotlin 中,为了获得与 Java 接口中的静态方法相同的结果,您应该使用 companion object
来声明您的静态方法。示例:
interface MyDevice {
// instance methods
companion object {
// static methods
@JvmStatic
fun setLocation(location: Location) {...}
@JvmStatic
fun getLocation(): Location {...}
}
}
注意 @JvmStatic
注释。当您从 Java class 调用这些 Kotlin 函数时,它们将被解释为静态方法。示例:
public void myJavaMethod() {
Location location = MyDevice.getLocation();
}
您描述的问题是缺少元数据 Kotlin 需要将静态方法视为 Class 扩展函数的扩展属性。
连同问题KT-11968,至少目前无法实现。
最好的选择是 API 转换为 Kotlin,并在必要时支持 @JvmStaic/@JvmField 和 @JvmDefault 以实现向后兼容性。
interface MyDevice {
companion object {
// nullable type or explicit init
var location: Location?
@JvmStatic get
@JvmStatic set
// kotlin
val x = MyDevice.location
MyDevice.location = x
// java
var x = MyDevice.getLocation();
MyDevice.setLocation(x);
kotlin lang 提供的解决方案很少,我们可以使用这些解决方案来简化您的案例。在 Java 之间做出更好的工作是 kotlin 的本质,对我来说,我没有看到使用 Companion/Object 创建类似于 Java 的静态方法有任何缺点。为了简单起见,kotlin 语言本身也为开发人员提供了许多方便的帮助程序。以下是我们可以申请的:
- 对象
object MyDevice {
@JvmStatic
fun getLocation(): Location {
}
@JvmStatic
fun setLocation(location: Location) {
}
}
- 同伴
class MyDevice {
companion object {
@JvmStatic
fun getLocation(): Location {
}
@JvmStatic
fun setLocation(location: Location) {
}
}
}
来电Java:
MyDevice.setLocation(location);
final Location location = MyDevice.getLocation();
阅读了专家的回答,研究了他们提供的链接,反编译了包装器的 Kotlin 代码 class 并分析了一个演示应用程序(纯 Java) Kotlin-wrapped 库,我决定更改 Java API.
现在我有一个 class 和一个 public 静态对象:
public class MyDevice {
public static MyDevice myDevice;
public void setLocation(Location location) {…}
public Location getLocation() {…}
}
现在 Java 消费者将使用
import static com.example.sdk.MyDevice.myDevice;
Kotlin 消费者不需要 static:
import com.example.sdk.MyDevice.myDevice
所以,我的库不需要单独的 Kotlin 风格!