Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在Kotlin中将静态Java方法用作静态(或单例)属性_Android_Kotlin_Sdk_Kotlin Java Interop - Fatal编程技术网

Android 在Kotlin中将静态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

我的SDK公开了一个只有静态方法的Java接口,例如

公共接口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风格!

    Singleton
    object
    更适合我,请参见。至于@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