我是Kotlin的新手,最近将一个简单的文件从java转换为Kotlin。我想知道为什么Android转换器将我的java类改为Kotlin对象。
爪哇:
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;
}
}
转换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
}
}
为什么不呢:
class MyClass {
... etc ...
}
非常感谢任何帮助。
答案 0 :(得分:91)
Kotlin's documentation对此非常好,所以请随意阅读。
这个问题的选择答案在解释中有一些不好的措辞,很容易误导人。例如,一个对象不是&#34;静态类per-say&#34;,而是a static instance of a class that there is only one of
,也称为单身。
显示差异的最好方法可能是以Java形式查看反编译的Kotlin代码。
这是一个Kotlin对象和类:
object ExampleObject {
fun example() {
}
}
class ExampleClass {
fun example() {
}
}
为了使用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() {
}
}
您可以通过以下方式在Kotlin中使用该对象:
ExampleObject.example()
将编译为等效的Java字节代码:
ExampleObject.INSTANCE.example()
为什么Kotlin会介绍object
s?
Kotlin中object
的主要用例是因为Kotlin试图废除静态和原语,让我们使用纯粹的面向对象语言。 Kotlin仍在底层使用static
和原语,但它不鼓励开发人员再使用这些概念。相反,现在Kotlin用单例对象实例替换静态。您之前在Java中使用静态字段的位置,在Kotlin中,您现在将创建object
,并将该字段放在object
中。
与Java的互操作性:
由于Kotlin与Java 100%可互操作,因此有时您会希望以更好的Java方式公开某些API或字段。为此,您可以使用@JvmStatic
注释。通过使用object
注释@JvmStatic
中的字段或函数,它将编译为Java可以更容易使用的静态字段。
伴侣对象:
值得一提的最后一件事是companion object
。在Java中,您通常具有包含一些静态内容的类,但也包含一些非静态/实例内容。 Kotlin允许您对伴随对象执行类似操作,object
绑定到class
,这意味着类可以访问它的伴随对象的私有函数和属性:< / p>
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)
}
}
答案 1 :(得分:70)
Kotlin对象就像一个无法实例化的类,因此必须按名称调用它。 (静态类本身)
安卓转换器看到你的类只包含一个静态方法,所以它将它转换为Kotlin对象。
在此处详细了解:http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects
答案 2 :(得分:8)
对象是单身人士。您无需创建实例即可使用它。
需要实例化一个类才能使用
与Java中的方法相同,您可以说Math.sqrt(2)并且您不需要创建Math实例来使用sqrt,在Kotlin中您可以创建一个对象来保存这些方法,它们实际上是静态的。
这里有一些信息:
https://kotlinlang.org/docs/reference/object-declarations.html
IntelliJ显然非常聪明,可以检测到你需要一个对象,因为你只有静态java方法。
答案 3 :(得分:6)
区别:对象 || 类 || 伴随对象 || 数据类
object MyClass{}
中,默认整个变量只有一个引用,但在 companion object
中,您可以选择创建静态方法或创建静态变量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)
答案 4 :(得分:3)
您也可以在没有对象声明的情况下定义函数。只是在.kt文件中 例如:
fun GenerateChecksumCrc16(bytes: ByteArray): Int {
...
}
此函数与包中声明了.kt文件有关。 您可以在https://kotlinlang.org/docs/reference/packages.html
了解更多相关信息答案 5 :(得分:2)
以@ speirce7的答案为基础:
以下代码显示了涉及Kotlin的类和对象之间的基本区别:
isprime()