public class HelloClass {
public void FullName(String firstName, String lastName) {
String fullName = firstName + " " + lastName;
System.out.println("My name is : " + fullName);
}
public void Age() {
int age = 21;
System.out.println("My age is : " + age);
}
public static void main(String args[]) {
HelloClass hello = new HelloClass();
hello.FullName("John","Doe");
hello.Age();
}
}
Kotlin
class NameClass {
fun FullName(firstName: String, lastName:String) {
var fullName = "$firstName $lastName"
println("My Name is : $fullName")
}
}
fun Age() {
var age : Int
age = 21
println("My age is: $age")
}
fun main(args: Array<String>) {
NameClass().FullName("John","Doe")
Age()
}A sensação do código não é tão diferente, além de algumas pequenas alterações de sintaxe nos métodos e nas classes.
Mas a diferença real aqui é que o Kotlin suporta inferência de tipo onde o tipo de variável não precisa ser declarado. Também não precisamos de ponto e vírgula ( ; ) não mais.
Também podemos observar que o Kotlin não impõe estritamente OOP como Java, onde tudo deve estar contido dentro de uma classe. Dê uma olhada fun Age e fun main no exemplo em que não está contido em nenhuma classe.
O Kotlin também costuma ter menos linhas de códigos, enquanto o Java adere mais à abordagem tradicional de tornar tudo detalhado.
Uma vantagem do Kotlin sobre Java é a flexibilidade do Kotlin – ele pode optar por fazer tudo na abordagem OOP tradicional ou pode seguir um caminho diferente.
Expressões Lambda
Se estamos falando sobre Java e Kotlin, é claro que temos que falar sobre a famosa expressão lambda. O Kotlin possui suporte nativo ao Lambda (e sempre possui), enquanto o lambda foi introduzido pela primeira vez no Java 8.
Vamos ver como os dois se parecem.
Java
//syntaxes
parameter -> expression
(parameter1, parameter2) -> { code }
//sample usage
ArrayList<Integer> numbers = new ArrayList<Integer>();
numbers.add(5);
numbers.add(9);
numbers.forEach( (n) -> { System.out.println(n); } );Kotlin
//syntax
{ parameter1, parameter2 -> code }
//sample usage
max(strings, { a, b -> a.length < b.length })Em Java, os parênteses são mais brandos: se existir apenas um parâmetro, não há necessidade de parênteses. Mas nos suportes Kotlin são sempre necessários. No geral, no entanto, não há muitas diferenças além da sintaxe.
Na minha opinião, as funções lambda não serão usadas muito além de usá-las como métodos de retorno de chamada. Embora as funções lambda tenham muito mais usos, legibilidade questões o tornam menos desejável. Eles tornarão seu código mais curto, mas descobrir o código mais tarde será muito mais difícil.
É apenas uma questão de preferência, mas acho útil que Kotlin aplique os colchetes obrigatórios para ajudar na legibilidade.
Tratamento nulo
Em uma linguagem orientada a objetos, valores de tipo nulo sempre foram um problema. Esse problema ocorre na forma de uma exceção de ponteiro nulo (NPE) quando você está tentando usar o conteúdo de um valor nulo.
Como as NPEs sempre foram um problema, Java e Kotlin têm sua própria maneira de manipular objetos nulos, como mostrarei abaixo.
Java
Object object = objServ.getObject();
//traditional approach of null checking
if(object!=null){
System.out.println(object.getValue());
}
//Optional was introduced in Java 8 to further help with null values
//Optional nullable will allow null object
Optional<Object> objectOptional = Optional.ofNullable(objServ.getObject());
//Optional.of - throws NullPointerException if passed parameter is null
Optional<Object> objectNotNull = Optional.of(anotherObj);
if(objectOptional.isPresent()){
Object object = objectOptional.get();
System.out.println(object.getValue());
}
System.out.println(objectNotNull.getValue());Kotlin
//Kotlin uses null safety mechanism
var a: String = "abc" // Regular initialization means non-null by default
a = null // compilation error
//allowing null only if it is set Nullable
var b: String? = "abc" // can be set null
b = null // ok
print(b)Desde que me lembro, o Java tem usado a verificação nula tradicional, propensa a erros humanos. Em seguida, o Java 8 saiu com classes opcionais que permitem uma verificação nula mais robusta, especialmente do lado da API / servidor.
Kotlin, por outro lado, fornece variáveis de segurança nulas em que a variável deve ser anulável se o valor puder ser nulo.
Ainda não usei a classe opcional, mas o mecanismo e o objetivo parecem bastante semelhantes à segurança nula de Kotlin. Ambos ajudam a identificar qual variável pode ser nula e ajudam a garantir que a verificação correta seja implementada.
Às vezes, no código, pode haver muitas variáveis por aí e muitas para verificar. Mas adicionar verificações em todos os lugares torna nossa base de código feia e ninguém gosta disso, certo?
Na minha opinião, porém, usar o opcional do Java parece um pouco confuso por causa da quantidade de código que precisa ser adicionado para as verificações. Enquanto isso, no Kotlin, você pode adicionar uma pequena quantidade de código para fazer uma verificação nula para você.
Classe de modelo
Algumas pessoas também podem se referir a isso como a classe Entity. Abaixo você pode ver como as duas classes são usadas como classes de modelo em cada idioma.
Java
public class Student {
private String name;
private Integer age;
// Default constructor
public Student() { }
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
}Kotlin
//Kotlin data class
data class Student(var name: String = "", var age: Int = 0)
//Usage
var student: Student = Student("John Doe", 21)Em Java, as propriedades são declaradas como privadas, seguindo a prática do encapsulamento. Ao acessar essas propriedades, o Java usa Getters e Setters, juntamente com os métodos isEqual ou toString, quando necessário.
No lado de Kotlin, classes de dados são introduzidos com o objetivo especial de classes de modelo. As classes de dados permitem que as propriedades sejam acessadas diretamente. Eles também fornecem vários métodos utilitários incorporados, como equals (), toString () e copy ().
Para mim, as classes de dados são uma das melhores coisas que o Kotlin oferece. Eles visam reduzir a quantidade do código padrão necessário para as classes de modelo regulares e fazem um bom trabalho nisso.
Variáveis globais
Às vezes, seu código pode precisar que uma variável precise ser acessada em qualquer lugar da sua base de códigos. É para isso que as variáveis globais são usadas. Kotlin e Java têm suas próprias maneiras de lidar com isso.
Java
public class SomeClass {
public static int globalNumber = 10;
}
//can be called without initializing the class
SomeClass.globalNumber;Kotlin
class SomeClass {
companion object {
val globalNumber = 10
}
}
//called exactly the same like usual
SomeClass.globalNumberAlguns de vocês já devem estar familiarizados com o estático palavra-chave aqui, pois também é usada em outra linguagem como C ++. Ele é inicializado no início da execução de um programa e é usado pelo Java para fornecer variáveis globais, pois não está contido como um Objeto. Isso significa que ele pode ser acessado em qualquer lugar sem inicializar a classe como um objeto.
O Kotlin está usando uma abordagem bem diferente aqui: remove a palavra-chave estática e a substitui por uma objeto complementar que é bem parecido com um singleton. Permite implementar recursos sofisticados, como extensões e interfaces.
A falta da palavra-chave estática no Kotlin foi realmente bastante surpreendente para mim. Você pode argumentar que usar a palavra-chave estática pode não ser uma boa prática devido à sua natureza e porque é difícil de testar. E, com certeza, o objeto complementar Kotlin pode substituí-lo facilmente.
Mesmo assim, o uso de estática para variável global deve ser bastante simples. Se tomarmos cuidado e não criarmos o hábito de tornar tudo global, devemos ser bons.
O objeto complementar também pode nos dar alguma flexibilidade com a interface e tal, mas com que frequência estaremos interagindo com classes singleton?
Acho que palavras-chave estáticas nos ajudam a manter as coisas curtas e limpas para variáveis globais.
Concorrência
Atualmente, a simultaneidade é um tópico importante. Às vezes, a capacidade de uma linguagem de programação executar vários trabalhos simultaneamente pode ajudá-lo a decidir se esse será o seu idioma preferido.
Vamos dar uma olhada em como os dois idiomas abordam isso.
Java
// Java code for thread creation by extending
// the Thread class
class MultithreadingDemo extends Thread
{
public void run()
{
try
{
// Displaying the thread that is running
System.out.println ("Thread " +
Thread.currentThread().getId() +
" is running");
}
catch (Exception e)
{
// Throwing an exception
System.out.println ("Exception is caught");
}
}
}
// Main Class
public class Multithread
{
public static void main(String[] args)
{
int n = 8; // Number of threads
for (int i=0; i<n; i++)
{
MultithreadingDemo object = new MultithreadingDemo();
object.start();
}
}
}
Kotlin
for (i in 1..1000)
GlobalScope.launch {
println(i)
}
Java usa principalmente tópicos para apoiar a simultaneidade. Em Java, criar um encadeamento requer que você faça uma classe que se estenda à classe de encadeamento Java incorporada. O restante de seu uso deve ser bem direto.
Embora os threads também estejam disponíveis no Kotlin, você deve usar seu corotinas. As corotinas são basicamente threads leves que se destacam em tarefas curtas e sem bloqueio.
A simultaneidade sempre foi um conceito difícil de entender (e também de testar). A segmentação é usada há muito tempo e algumas pessoas podem já estar confortáveis com isso.
Ultimamente, as corotinas se tornaram mais populares com idiomas como o Kotlin e o Go (o Go também possui goroutines). O conceito difere um pouco dos threads tradicionais – as rotinas são seqüenciais, enquanto os threads podem trabalhar em paralelo.
Experimentar corotinas, no entanto, deve ser bem fácil, pois Kotlin faz um ótimo trabalho explicando-as em suas docs. E um bônus para o Kotlin sobre Java é a quantidade de código padrão que pode ser removido no Kotlin.
Funções de extensão
Você pode estar se perguntando por que estou trazendo isso à tona, já que o próprio Java nem possui esse recurso.
Mas não posso deixar de mencioná-lo, porque as funções de extensão são um recurso muito útil que foi introduzido no Kotlin.
fun Int.plusOne(): Int {
return this + 1
}
fun main(args: Array<String>) {
var number = 1
var result = number.plusOne()
println("Result is: $result")
}Eles permitem que uma classe tenha nova funcionalidade sem estendê-la para a classe ou usar qualquer um dos sofisticados Design Patterns. Ele ainda permite adicionar funcionalidades às classes variáveis do Kotlin.
Você pode praticamente dizer adeus ao método lib que precisa que você passe tudo dentro dos seus parâmetros.
Por último, mas não menos importante, vamos falar sobre algo não técnico. Primeiro, vamos dar uma olhada nesta pesquisa que mostra as principais linguagens de programação usadas em 2020.
Podemos ver que Java é uma das linguagens mais usadas. E enquanto o Kotlin ainda está crescendo muito em popularidade, a comunidade Java ainda permanece várias vezes maior que o Kotlin e provavelmente não mudará tão cedo.
Então, o que isso importa então? Na verdade, importa muito. Com a quantidade de pessoas na comunidade Java, é muito mais fácil encontrar referências e obter ajuda quando você precisar, na Internet e no mundo real.
Muitas empresas também ainda estão usando o Java como base e isso pode não mudar tão cedo, mesmo com a interoperabilidade do Kotlin com o Java. E, geralmente, fazer uma migração não serve a nenhum propósito comercial, a menos que a empresa tenha razões realmente importantes para isso.
Empacotando
Para aqueles que apenas rolam para o resumo, aqui está o que discutimos:
- Sintaxe: os padrões não diferem muito, exceto por pequenas diferenças de sintaxe, mas o Kotlin é mais flexível em vários aspectos.
- Expressões Lambda: a sintaxe é quase a mesma, mas o Kotlin usa colchetes para facilitar a legibilidade.
- Tratamento nulo: Java usa uma classe para ajudar no tratamento nulo, enquanto o Kotlin usa variáveis de segurança nulas incorporadas.
- Classes de modelo: Java usa classes com variáveis privadas e setter / getter enquanto o Kotlin o suporta com classes de dados.
- Variáveis globais: Java usa a palavra-chave estática, enquanto o Kotlin usa algo semelhante às subclasses.
- Concorrência: Java usa multi-threading, enquanto o Kotlin usa coroutines (que geralmente são mais leves).
- Funções de extensão: um novo recurso introduzido pelo Kotlin para dar funcionalidade facilmente às classes sem estendê-la.
- Comunidade: Java ainda reina supremo no aspecto da comunidade, o que facilita a aprendizagem e a obtenção de ajuda.
Existem muitos outros recursos que poderíamos comparar entre Java e Kotlin. Mas o que discuti aqui são, na minha opinião, alguns dos mais importantes.
Acho que vale a pena pegar Kotlin no momento. Do lado do desenvolvimento, ajuda a remover o código longo do clichê e manter tudo limpo e curto. Se você já é um programador Java, aprender o Kotlin não deve ser muito difícil e não há problema em demorar um pouco.
Obrigado pela leitura! Espero que este artigo o ajude a decidir qual linguagem de programação você deve escolher, Java ou Kotlin. E para qualquer coisa que esteja faltando, fique à vontade para deixar um feedback para mim, pois será muito apreciado.