Dicas na migração de Java para Kotlin
Tags: java, kotlin, programming
Published: 2020-08-31 11:00:08

Se você desenvolve em Java e tem interesse em aprender ou conhecer o Kotlin, muito provavelmente você já deu uma olhada em alguns códigos em Kotlin, principalmente se você conhece Android.

Além da similaridade das linguagens, existem pequenas diferenças que parecem confusas, mas acredite, elas vieram para facilitar a nossa vida!

Portanto, vou aproveitar este artigo para compartilhar algumas diferenças em relação ao Java focando em quem está aprendendo Kotlin agora, interessado? Então bora começar.

> You can [read a version of this article in english](https://dev.to/alexfelipe/tips-to-migrate-from-java-to-kotlin-59af).

## Rodando o programa apenas com uma função

Ao escrever um código Java, o nosso primeiro impacto começa na execução do programa:

```java
class Main {

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }

}
```

Mesmo que o seu programa execute apenas uma impressão, o método `main`, **bem verboso**, sempre estará presente! 

No Kotlin temos um cenário diferente:

```kotlin
fun main() {
    println("Hello World!")
}
```

Pois é, apenas isso é o suficiente para você rodar o seu `Hello World!`. 

> Também é válido notar que não precisamos escrever `;` no final da instrução, é **opcional e dispensável**.

## Declaração de variáveis e seus tipos

Ao declarar variáveis no Kotlin, somos obrigados a decidir se ela será mutável ou não, sendo `var` mutável e `val` imutável:

```kotlin
var name = "Alex"
name = "Alex Felipe"
val age = 26
age = 26 // doesn't compile
```

Essa é uma das características do Kotlin que mais gosto, pois o esforço para manter a imutabilidade no código é bem menor considerando o Java que precisa do `final`.

Observe também que não há a necessidade de declarar o tipo da variável.

> *"Isso significa que ela é dinamicamente tipada?"*

Assim como o Java, o Kotlin é estaticamente tipado, ou seja, ao declarar o valor para a variável, o tipo é atribuído de maneira implícita se não for declarado explicitamente, portanto, códigos como esse não compilam:

```kotlin
var name = "Alex"
name = 10 // doesn't compile
```

Se você é amante da escrita explícita, não fique triste, o Kotlin também permite declarar o tipo das variáveis:

```kotlin
var name: String = "Alex"
name = "Alex Felipe"
val age: Int = 26
age = 26 // doesn't compile
```

## Criando objetos

Ao trabalhar com linguagens orientadas a objeto, é natural a necessidade de criar objetos. No caso do Java, precisamos do `new` para isso, porém, no Kotlin o `new` não é nem uma palavra reservada!

> *"Então como criamos um objeto no Kotlin?"*

Considerando essa classe em Java:

```java
class Person {
    private String name;
    private int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
```

Criamos um objeto dela da seguinte maneira no Kotlin:

```kotlin
val alex = Person("Alex", 26)
val fran = new Person("Fran", 25) // doesn't compile
```

> Isso significa também que podemos criar variáveis com o nome `new` no Kotlin que ele compila!

## Propriedades ao invés de atributos

Além da diferença na criação de uma instância, também temos algumas mudanças na declaração de classes. No exemplo da classe `Person`, temos os atributos `name` e `age` para armazenar o estado do objeto.

Essa abordagem é bastante comum no Java e em várias linguagens OO. Porém, no Kotlin, ao invés de declarar atributos, declaramos propriedades!

> *"Mas qual é a diferença entre um atributo e propriedade?"*

A principal diferença está relacionada no acesso aos atributos. 

Quando trabalhamos com atributos, a boa prática é implementar métodos de acesso como getters e setters para realizar a leitura ou escrita:

```java
class Person {
    private String name;
    private int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
```

Dessa forma, evitamos que outras pessoas consigam manipular os atributos da classe diretamente sem um possível filtro. 

Com propriedades temos esse comportamento por padrão:

```kotlin
class Person {
    var name: String
    var age: Int
    
    constructor(name: String, age: Int){
        this.name = name
        this.age = age
    }
}
```
> [No Kotlin temos mais de um construtor](https://kotlinlang.org/docs/reference/classes.html#constructors), o primário e o secundário. Nesta implementação foi utilizado o secundário, mas o primário é o mais comum.

Em outras palavras, quando acessamos `name` ou `age` de uma classe Kotlin, na verdade estamos acessando o setter e o getter! Bem mais simples, né?

Inclusive, dentro de um código Java, ao tentar acessar o `name` ou `age` dessa classe em Kotlin, você terá acesso apenas aos setters ou getters 😁

## Modificando o `set` e `get` da propriedade

Essa diferença pode soar estranho a princípio, sendo assim, para ficar mais claro, podemos também deixar os métodos de acesso das propriedades visíveis:

```kotlin
class Person {
    var name: String
    set(value) {
        field = value
        println("Setting the name $value")
    }
    get() {
        println("Getting the name $field")
        return field
    }
    var age: Int

    constructor(name: String, age: Int){
        this.name = name
        this.age = age
    }
}
```

Ao realizar o teste com esse trecho de código:

```kotlin
val alex = Person("Alex", 26)
alex.name = "Alex Felipe"
println(alex.name)
```

Temos o seguinte resultado:

```
Setting the name Alex
Setting the name Alex Felipe
Getting the name Alex Felipe
Alex Felipe
```

Note que até mesmo a própria classe, durante a construção do objeto, também acessa diretamente o setter da propriedade! 

Outro ponto a se notar, é que dentro do `set` e `get` utilizamos o `field` para atribuir e pegar o valor da propriedade.

Em outras palavras, o `field` é o atributo da propriedade, é nele que armazenamos o estado do `name` e só acessível dentro do escopo do `set` ou `get`.

Isso significa que durante o `set`, se não modificarmos o `field` não somos capazes de alterar o valor:

```kotlin
set(value) {
    println("Setting the name $value")
}
```

Realizando o mesmo teste, temos o seguinte resultado:

```
Setting the name Alex
Setting the name Alex Felipe
Getting the name null
null
```

## Modelos de `String`

Um outro ponto que provavelmente você estranhou, é a forma como concatenamos `String`s sem a necessidade do operador `+` e tudo dentro da `""`. 

No Kotlin, essa técnica é chamada de modelos de `String` ([`String` templates](https://kotlinlang.org/docs/reference/basic-types.html#string-templates)), também conhecida como interpolação de `String` em outras linguagens. 

Basicamente, por meio dela somos capazes de embutir código dentro de `String`, seja apenas uma leitura conforme o exemplo, como também funções ou operações:

```kotlin
println("1 + 2 = ${1 + 2}")
```

Temos o seguinte resultado:

```
1 + 2 = 3
```

A diferença nesse caso, é que a execução de instrução precisa ficar dentro de `{}`, isso também é necessário quando acessamos um membro de um objeto também:

```kotlin
println("My name is ${alex.name}")
```

## Conclusão

Além das dicas que vimos neste artigo, o Kotlin oferece muitas outras funcionalidades e diferenças em relação ao Java. Muitas delas foram feitas para facilitar a vida de quem escreve código, ou seja, escrever e ler menos código e obter mais resultado!

Ficou interessado no Kotlin e quer aprender mais? Você pode acompanhar mais conteúdos que produzi [neste agregador de conteúdo que mantenho](https://medium.com/collabcode/seja-tamb%C3%A9m-um-desenvolvedor-kotlin-770188949486).

O que achou das dicas, gostou? Se sim, aproveite para deixar o seu like, comentário e compartilhe com outras pessoas que querem aprender também 😉