Kotlin中的类和对象之间的区别

Cru*_*234 81 java android kotlin

我是Kotlin的新手,最近将一个简单的文件从java转换为Kotlin.我想知道为什么Android转换器将我的java类改为Kotlin对象.

Java的:

public class MyClass {
    static public int GenerateChecksumCrc16(byte bytes[]) {

        int crc = 0xFFFF;
        int temp;
        int crc_byte;

        for (byte aByte : bytes) {

            crc_byte = aByte;

            for (int bit_index = 0; bit_index < 8; bit_index++) {

                temp = ((crc >> 15)) ^ ((crc_byte >> 7));

                crc <<= 1;
                crc &= 0xFFFF;

                if (temp > 0) {
                    crc ^= 0x1021;
                    crc &= 0xFFFF;
                }

                crc_byte <<= 1;
                crc_byte &= 0xFF;

            }
        }

        return crc;
    }
}
Run Code Online (Sandbox Code Playgroud)

转换Kotlin:

object MyClass {
    fun GenerateChecksumCrc16(bytes: ByteArray): Int {

        var crc = 0xFFFF
        var temp: Int
        var crc_byte: Int

        for (aByte in bytes) {

            crc_byte = aByte.toInt()

            for (bit_index in 0..7) {

                temp = crc shr 15 xor (crc_byte shr 7)

                crc = crc shl 1
                crc = crc and 0xFFFF

                if (temp > 0) {
                    crc = crc xor 0x1021
                    crc = crc and 0xFFFF
                }

                crc_byte = crc_byte shl 1
                crc_byte = crc_byte and 0xFF

            }
        }

        return crc
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么不是:

class MyClass {
    ... etc ...
}
Run Code Online (Sandbox Code Playgroud)

非常感谢任何帮助.

spi*_*ce7 130

Kotlin关于此的文档相当不错,所以请随意阅读.

这个问题的选择答案在解释中有一些不好的措辞,很容易误导人.例如,一个对象不是"每个说的静态类",而是它a static instance of a class that there is only one of,也就是称为单例.

也许展示差异的最好方法是以Java形式查看反编译的Kotlin代码.

这是一个Kotlin对象和类:

object ExampleObject {
  fun example() {
  }
}

class ExampleClass {
  fun example() {
  }
}
Run Code Online (Sandbox Code Playgroud)

为了使用它ExampleClass,你需要创建它的一个实例:ExampleClass().example()但是对于一个对象,Kotlin会为你创建一个单独的实例,而你永远不会调用它的构造函数,而只是通过使用它来访问它的静态实例名字:ExampleObject.example().

这是Kotlin将生成的等效Java代码:

Kotlin编译为Java字节代码,但如果我们将上面编译的Kotlin代码反向编译为Java代码,这就是我们得到的:

public final class ExampleObject {
   public static final ExampleObject INSTANCE = new ExampleObject();

   private ExampleObject() { }

   public final void example() {
   }
}

public final class ExampleClass {
   public final void example() {
   }
}
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式在Kotlin中使用该对象:

ExampleObject.example()
Run Code Online (Sandbox Code Playgroud)

这将编译为等效的Java字节代码:

ExampleObject.INSTANCE.example()
Run Code Online (Sandbox Code Playgroud)

为什么Kotlin会介绍objects?

objectKotlin 的主要用例是因为Kotlin试图废除静态和原语,让我们使用纯粹的面向对象语言.Kotlin仍然static在引擎盖下使用和原语,但它不鼓励开发者再使用这些概念.相反,现在Kotlin用单例对象实例替换静态.你以前在Java中使用静态字段的地方,在Kotlin中,你现在将创建一个object,并将该字段放入object.

与Java的互操作性:

由于Kotlin与Java 100%可互操作,因此有时您会希望以更好的Java方式公开某些API或字段.为此,您可以使用@JvmStatic注释.通过在objectwith中注释字段或函数@JvmStatic,它将编译为Java可以更容易使用的静态字段.

伴侣对象:

最后一件值得一提的是companion objects.在Java中,您通常具有包含一些静态内容的类,但也包含一些非静态/实例内容.Kotlin允许你做一些类似于伴随对象的东西,它们object与a绑定class,这意味着一个类可以访问它的伴随对象的私有函数和属性:

class ExampleClass {
  companion object {
    // Things that would be static in Java would go here in Kotlin
    private const val str = "asdf"
  }

  fun example() {
    // I can access private variables in my companion object
    println(str)
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的解释。非常感谢。 (4认同)

小智 84

Kotlin对象就像一个无法实例化的类,因此必须按名称调用它.(静态类本身)

android转换器看到你的类只包含一个静态方法,所以它将它转换为Kotlin对象.

在这里阅读更多相关信息:http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects


Bru*_*owe 11

对象是单身.您无需创建实例即可使用它.

需要实例化一个类才能使用

与在Java中相同的方式,您可以说Math.sqrt(2)并且您不需要创建Math实例来使用sqrt,在Kotlin中您可以创建一个对象来保存这些方法,它们实际上是静态的.

这里有一些信息:

https://kotlinlang.org/docs/reference/object-declarations.html

IntelliJ显然足够聪明,可以检测到您需要一个对象,因为您只有静态Java方法.


San*_*inh 7

之间的区别:对象|| || 伴生对象|| 数据类

1.对象

  • 对象声明在第一次访问时被延迟初始化。
  • 对象就像单例类
  • 整个应用程序只有一个参考
  • 访问成员、方法,无需创建实例

2.班级

  • 您可以创建多个参考
  • 需要为访问成员、方法创建实例

3.伴侣对象

  • 当加载相应的类时初始化一个伴生对象
  • object MyClass{}默认情况下,全局变量有一个参考,但companion object你必须选择创建静态方法或创建静态变量
  • 您可以创建单例类

4.数据类

  • 用于保存数据/状态的类
  • Kotlin 的数据类,你不需要自己编写/生成所有冗长的样板代码
  • 编译器自动为所有可变属性生成默认的 getter 和 setter
  • 编译器会自动派生出标准方法的实现,例如equals(),hashCode()toString()

例子

//---------------1- object ----------------------
object MyClass1 {
        fun checkData {
            // ...
        }
}

MyClass1.checkData()  // call method


//----------------2- class ---------------------
class MyClass2 {
        fun checkData {
            // ...
        }
}

var myClass = MyClass2()
myClass.checkData()  // call method



//----------------3- companion object ---------------------
class MyClass3 {
        companion object {
            fun myStaticMethod() {
                // ...
            }
        }

       fun myInstanceMethod() {
            // ...
        }
}
MyClass3.myStaticMethod() // call companion object member
var myClass = MyClass3()
myClass.myInstanceMethod()  // call simple method using reference

//----------------4- data class ---------------------
data class MyClass4(val name: String, val rId: Int)
Run Code Online (Sandbox Code Playgroud)