https://my.oschina.net/u/3847608/blog/1837610
Desta vez, falei sobre as variáveis e constantes de Kotlin e apresentarei principalmente o seguinte:
- 1. Definição básica de variáveis
- 2. A diferença entre var e val
- 3. Inferência de tipo inteligente
- 4. Acessador de atributo personalizado
- 5. Var é variável e val deve ser imutável?
1. Comparação de uso variável e constante em Kotlin e Java
- 1. Defina uma variável e constante em Java
public String name = "Mikyou";//定义变量
public final int age = 18;//final定义常量
- 2. Defina uma variável e constante em Kotlin
var name: String = "Mikyou"
val age: Int = 18
ou
var name = "Mikyou"
val age = 18
Resumo: a partir da comparação acima, podemos obter:
- 1. Kotlin define uma variável e constante mais concisa e flexível que Java
- 2. O Kotlin possui um mecanismo de inferência de tipo.Quando uma variável ou constante é inicializada, a declaração de tipo pode ser omitida, e será usada como o tipo da variável de acordo com o tipo do valor inicializado.
- 3. Kotlin declara que variáveis e constantes devem usar var (variável), val (constante) palavra-chave começa, depois nome e, finalmente, tipo (se houver um tipo de valor inicializado, ele pode ser omitido diretamente)
- 4. Comparado com Java, o modificador de acesso padrão do Kotlin é público e Java é o padrão
- 5. Java geralmente começa com o tipo e depois com o nome, e o tipo não pode ser omitido; esse tipo de operação não é possível no Kotlin. Como o tipo pode ser omitido em Kotlin, ou seja, o tipo é relativamente fraco, então Kotlin colocará o tipo no final, geralmente contendo o valor de inicialização omitirá a declaração de tipo subsequente.
Dois, o uso constante e variável de Kotlin
var name: String = "Mikyou"
var address: String?//如果这个变量没有初始化,那么需要显示声明类型并且指明类型是否可null
address = "NanJing"
val age: Int = 18
ou
var name = "Mikyou"
val age = 18
- 1. Variáveis e declarações de constantes devem começar com as palavras-chave "var" e "val".
- 2. A estrutura de variáveis e constantes: (var ou val) Nome: (Vírgula dividida) Tipo de variável = valor de inicialização.
- 3. Conversão de tipo inteligente (o compilador avisa como elenco inteligente). Se a variável ou constante contém o valor inicial, o tipo pode ser omitido. O compilador irá analisar o tipo do valor inicializado como a variável e o tipo constante por padrão.
- 4. Se a variável não for inicializada, o tipo declarado precisa ser exibido e se o tipo é anulável ou não precisa ser especificado.
Três, acessador de atributo personalizado de Kotlin
Os atributos são o recurso de primeira classe em Kotlin. Eles são usados para substituir campos e métodos setter e getter em Java por um atributo. Os acessadores set e get em Kotlin são equivalentes aos métodos setter e getter em Java. Um novo recurso do Kotlin é que você pode definir acessores para propriedades em uma classe, incluindo acessores setter e getter. Esse recurso é muito adequado para um novo atributo que precisa ser calculado por meio da lógica de vários atributos. Então, a operação do processo de cálculo lógico não precisa abrir um método como o Java para conseguir. Você pode executar operações lógicas diretamente no acessador de atributo.
- 1. Acessador de atributo personalizado
Implementado em Java:
public class Rectangle {
private float width;
private float height;
public Rectangle(float width, float height) {
this.width = width;
this.height = height;
}
public boolean isSquare() {//在java中实现一个方法进行相关的逻辑计算
return width == height;
}
}
Implementado em Kotlin:
class Rectangle(width: Float, height: Float) {
val isSquare: Boolean//在Kotlin中只需要一个属性就能解决,重新定义了isSquare的getter属性访问器,访问器中可以写入具体逻辑代码。
get() {
return width == height
}
}
- 2. Acessador de atributo de definição personalizada
Implemente um método setter em uma visualização customizada no Android em Java.
public class RoundImageView extends ImageView {
...
public void setBorderColor(int color) {
mColor = color;
invalidate();
}
...
}
Implemente o acessador de atributo definido em uma visualização personalizada no Android em Kotlin.
class RoundImageView @JvmOverloads constructor(context: Context, attributeSet: AttributeSet? = null, defAttrStyle: Int = 0)
: ImageView(context, attributeSet, defAttrStyle) {
var mBorderColor: Int
set(value) {//自定义set属性访问器
field = value
invalidate()
}
}
Quarto, a diferença entre var e val em Kotlin
- 1, referência de variável var (da variável) . E o valor da variável modificada por ele pode ser alterado, com permissões de leitura e gravação, o que equivale a variáveis não finais em Java.
- 2. Val (do valor) é uma referência imutável . E o valor da variável modificada por ele geralmente é inicializado e não pode ser relançado no estágio posterior, caso contrário, ele lançará uma exceção de compilação ( esta frase será discutida, consulte a discussão sobre val imutável e legível em Kotlin ) , que são constantes modificadas finais equivalentes em Java.
- 3. No processo de desenvolvimento do Kotlin, use a palavra-chave val para declarar todas as variáveis do Kotlin o máximo possível. Use var apenas em alguns casos especiais. Todos nós sabemos que as funções no Kotlin são cidadãos de primeira classe e muito conteúdo de programação funcional O uso de variáveis referenciadas imutáveis o torna mais próximo do estilo de programação funcional.
- 4. Deve-se notar que a referência val em si é imutável, mas o objeto para o qual ela aponta pode ser mutável ( para discussão e verificação deste problema, consulte a discussão sobre val imutável e legível em Kotlin ).
- 5. A palavra-chave var permite alterar seu valor, mas seu tipo não pode ser alterado.
5. Discussão sobre imutabilidade e legibilidade de val em Kotlin
Uma vez que Kotlin é uma nova linguagem, frequentemente nos lembramos de alguns dos chamados teoremas no processo de aprendizagem e não nos aprofundamos realmente em por que esse é o caso. Por exemplo, pegando o tópico de hoje, acredito que muitas pessoas pensam (incluindo eu no início) que as variáveis modificadas de var são mutáveis, enquanto as variáveis modificadas de val são imutáveis. Então, depois de aprender o acessador de atributo personalizado de Kotlin, você sentirá que há um problema. Depois fui dar uma olhada em alguns blogs estrangeiros, embora existam descrições, depois de lê-las, o que me deixa ainda mais confuso é que o valor da variável modificada por val pode ser alterado e lido, e a referência subjacente também é alterada. A primeira frase é realmente compreensível, mas a última frase ainda é reservada. Então comecei a escrever autenticação de demonstração. Citando a frase original de um blog estrangeiro "Mas podemos dizer que val garante que a referência subjacente ao objeto é imutável? Não ..." endereço de origem do blog estrangeiro
- 1. A suposição de que val é imutável e legível
Hipótese 1: A variável modificada por val em Kotlin não pode ser considerada imutável, somente pode-se dizer que a permissão da variável modificada por val é legível.
Hipótese 2: A referência à variável modificada por val em Koltin é imutável, mas o objeto apontado é variável.
- 2. Argumento de que val é imutável e legível
Argumento Hipótese 1: Durante nosso desenvolvimento em Kotlin, as variáveis modificadas com val não podem ser atribuídas novamente, caso contrário, uma exceção de tempo de compilação será lançada. Mas o fato de não poder ser atribuído novamente não significa que seja imutável. Porque Kotlin é diferente de Java no recurso de acessadores de atributos personalizados. Esse recurso parece contradizer a imutabilidade da variável modificada por val. Esse problema não existe em Java. Se variáveis modificadas finais forem usadas, não há o chamado conceito de acessador personalizado.
fun main(args: Array<String>) {
val name = "Hello Kotlin"
name = "Hello Java"
}
erro de impressão:
Error:(8, 5) Kotlin: Val cannot be reassigned
Definir obter exemplo de acessador de atributo
class RandomNum {
val num: Int
get() = Random().nextInt()
}
fun main(args: Array<String>) {
println("the num is ${RandomNum().num}")
}
resultado de impressão:
the num is -1411951962
the num is -1719429461
Resumo: O exemplo acima pode mostrar que a Hipótese Um é verdadeira. A variável modificada por val em Kotlin não pode ser considerada imutável, mas apenas tem permissões legíveis.
Hipótese 2 do argumento: a partir do argumento 1, sabemos que a variável modificada pelo val de Kotlin é mutável, então sua referência subjacente é mutável? Um blog estrangeiro diz que as citações variam, é verdade? Através de um exemplo para ilustrar.
Classe de usuário:
package com.mikyou.kotlin.valtest
open class User() {
var name: String? = "test"
var age: Int = 18
var career: String? = "Student"
}
Aula do aluno:
class Student() : User()
Categoria de professor:
class Teacher() : User()
Interface do cliente:
interface Customer {
val user: User//注意: 这里是个val修饰的User实例引用
}
Classe de implementação VipCustomer:
class VipCustomer : Customer {
override val user: User
get() {
// return Student().apply {
// name = "mikyou"
// age = 18
// career = "HighStudent"
// }
return Teacher().apply {
//看到这里很多人肯定认为,底层引用也会发生改变,毕竟Student, Teacher是不同的对象了。但是事实是这样的吗?
name = "youkmi"
age = 28
career = "HighTeacher"
}
}
}
teste:
fun main(args: Array<String>) = VipCustomer().user.run {
println("my name is $name, I'm $age years old, my career is $career, my unique hash code is ${hashCode()} ")
}
resultado de impressão:
my name is mikyou, I'm 18 years old, my career is HighStudent, my unique hash code is 666988784
//切换到Teacher
my name is youkmi, I'm 28 years old, my career is HighTeacher, my unique hash code is 666988784
Resumo: A partir do exemplo acima, pode-se mostrar que a hipótese dois é verdadeira Dois hashCodes de objeto diferentes indicam que o endereço de referência do usuário não foi alterado e o objeto para o qual a referência aponta pode ser alterado.
Este é o fim da gramática básica da entrada do Kotlin. O próximo artigo continuará a mergulhar no conteúdo relacionado ao Kotlin