Android 在Kotlin中将静态Java方法用作静态(或单例)属性
我的SDK公开了一个只有静态方法的Java接口,例如Android 在Kotlin中将静态Java方法用作静态(或单例)属性,android,kotlin,sdk,kotlin-java-interop,Android,Kotlin,Sdk,Kotlin Java Interop,我的SDK公开了一个只有静态方法的Java接口,例如 公共接口MyDevice{ 公共静态void setLocation(位置位置){…} 公共静态位置getLocation(){…} } 在使用SDK的Java应用程序中,我的客户可以像使用singleton一样使用它们 Location currentLocation=MyDevice.getLocation(); 当此SDK集成到Kotlin应用程序中时,自然会将其表示为属性: val currentLocation=MyDevice
公共接口MyDevice{
公共静态void setLocation(位置位置){…}
公共静态位置getLocation(){…}
}
在使用SDK的Java应用程序中,我的客户可以像使用singleton一样使用它们
Location currentLocation=MyDevice.getLocation();
当此SDK集成到Kotlin应用程序中时,自然会将其表示为属性:
val currentLocation=MyDevice.location
问题是,这种内置互操作仅适用于非静态方法
我可以在Kotlin中创建一个singleton并让它处理转换:
对象myDevice{
变量位置:位置
get()=MyDevice.getLocation()
设置(位置)=MyDevice.setLocation(位置)
}
但是,在一个只有Java的SDK中,这个Kotlin文件不会对不使用Kotlin的客户产生负面影响吗?可以用Java来表示吗
或者我应该简单地将MyDevice.java转换成Kotlin?对于仍然使用Java的客户来说,这样的步骤会有什么负面影响?在Kotlin中,为了获得与Java接口中的静态方法相同的结果,您应该使用
伴随对象来声明您的静态方法。例如:
interface MyDevice {
// instance methods
companion object {
// static methods
@JvmStatic
fun setLocation(location: Location) {...}
@JvmStatic
fun getLocation(): Location {...}
}
}
public void myJavaMethod() {
Location location = MyDevice.getLocation();
}
请注意@JvmStatic
注释。当您从Java类调用这些Kotlin函数时,它们将被解释为静态方法。例如:
interface MyDevice {
// instance methods
companion object {
// static methods
@JvmStatic
fun setLocation(location: Location) {...}
@JvmStatic
fun getLocation(): Location {...}
}
}
public void myJavaMethod() {
Location location = MyDevice.getLocation();
}
您描述的问题是缺少元数据,Kotlin需要将静态方法视为扩展函数的类扩展属性
再加上这个问题,至少现在还不可能
最好的选择是将API转换为Kotlin,并支持@JvmStaic/@JvmField和@JvmDefault(如果需要向后兼容)
接口设备{
伴星{
//可为null的类型或显式init
变量位置:位置?
@JvmStatic get
@JVMS静态集
//科特林
val x=MyDevice.location
MyDevice.location=x
//爪哇
var x=MyDevice.getLocation();
MyDevice.setLocation(x);
kotlin lang提供的解决方案很少,我们可以用它简化您的案例。kotlin的本质是在Java之间更好地工作,对我来说,我没有看到使用Companion/Object创建类似Java的静态方法的任何缺点。kotlin语言本身也为开发人员提供了许多方便的帮助为了简单起见,我们可以应用以下内容:
反对
同伴
Java调用:
MyDevice.setLocation(location);
final Location location = MyDevice.getLocation();
阅读了专家的答案,研究了他们提供的链接,反编译了包装类的Kotlin代码,分析了使用Kotlin包装库的演示应用程序(纯Java),我决定更改Java API
现在我有了一个带有公共静态对象的类:
public class MyDevice {
public static MyDevice myDevice;
public void setLocation(Location location) {…}
public Location getLocation() {…}
}
现在Java用户将使用
import static com.example.sdk.MyDevice.myDevice;
Kotlin消费者不需要这种静态:
因此,我的库不需要单独的Kotlin风格!Singletonobject
更适合我,请参见。至于@JvmStatic,您是对的,如果我决定将MyDevice.java转换为Kotlin,应该使用它。但即使如此,在Kotlin中显式定义了一个属性,代码看起来更干净,java访问也是一样的。这是一个n有趣的链接,是的,我倾向于API转换到Kotlin。问题仍然是,这种转换有什么危险或黑暗面?它不会给我的库引入不必要的依赖关系吗?增加大小?需要更高的minSdkVersion?Apk大小-可能是的,你最好在转换后检查差异,因为compaNION对象是DEX文件中的一个额外的分配和类/方法声明。检查R8或Rex如何缩小您的APK,如果您使用其中任何一个。只要使用JVMMAPTION 1.6的Kotlin,就不太可能需要MIDSDK凸块。至于依赖关系,这取决于您认为不必要的,有人可以说kotlin stdlib是U。N必要的dep,但不太可能有额外的dep。使用java和kotlin用例编辑。检查MyDevice生成的字节码
import com.example.sdk.MyDevice.myDevice