Kotlin的属性和参数有什么区别?

J A*_*dag 4 kotlin

下面是一个类的简单示例,其中包含括号内的一些代码(属性)

class Person(firstName: String) {
....
}
Run Code Online (Sandbox Code Playgroud)

现在这里是一个函数的示例,其中包含括号内的一些代码(参数)

fun double(x: Int) {
...
}
Run Code Online (Sandbox Code Playgroud)

我知道这是一个基本问题,但作为初学者我很困惑.

nha*_*man 10

您将参数传递给函数和构造函数,具有属性.

Person示例中类的构造函数只有一个参数,double函数也是如此.在这种情况下,firstName参数不是属性!

要使它成为属性,您必须声明它:

class Person(firstName: String) {

  val firstName : String = firstName
}
Run Code Online (Sandbox Code Playgroud)

Kotlin允许它更短,这使得firstName参数作为属性:

class Person(val firstName: String)
Run Code Online (Sandbox Code Playgroud)

  • 这并不能解释什么;你只是说它们不同。为什么有人会使用其中一种而不是另一种? (3认同)

hol*_*ava 7

首先,您的firstName也是一个参数而不是类中的属性Person

//           v-- a parameter declared on primary constructor
class Person(firstName: String)
Run Code Online (Sandbox Code Playgroud)

您可以访问块或属性/字段声明中主构造函数上声明的参数init,例如:

class Person(firstName: String){
   val first:String
   init{ first=firstName }
}

class Person(firstName: String){
   val first:String = firstName
}

class Person(firstName: String){
   @JvmField val first:String = firstName
}
Run Code Online (Sandbox Code Playgroud)

要使 成为firstName属性,您可以使用关键字valvar,例如:

//            v--- immutable property
class Person(val firstName: String)

//            v--- mutable property
class Person(var firstName: String)
Run Code Online (Sandbox Code Playgroud)

Kotlin 属性将生成java 字节码的getter/setter(?) 和支持字段(?) 。以 Java 字节码的可变属性为例,如下所示:

public final class Person{
   private String firstName; // backing field

   //                   v--- parameter
   public Person(String firstName){ this.firstName = firstName; }

   //getter
   public final String getFirstName(){ return firstName; }

   //setter
   public final String setFirstName(String firstName){ this.firstName= firstName; }
}
Run Code Online (Sandbox Code Playgroud)

仅在函数作用域/构造函数作用域中可见的参数,但在主构造函数上声明的参数除外。

注意:参数是不可变的,就像 java effective-final变量/参数一样,所以你不能在 Kotlin 中重新分配参数,例如:

fun foo(bar:String){
   bar = "baz"
// ^--- compile error  
}
Run Code Online (Sandbox Code Playgroud)

  • 因此,真正的区别在于参数只能在构造函数中访问,例如“init()”。而属性可以在整个班级中访问。本质上这是一个范围问题。正确的? (3认同)