Java는 프로그래밍 언어 중 압도적인 위치를 차지하고 있기 때문에 Java 개발자가 Kotlin을 사용하면서 동일한 실수를 저지르는 것을 여러 번 봅니다. 오해하지 마세요. 이것이 버그라고 말하는 것이 아니라 개발자가 Java 개발에 익숙하고 Kotlin의 기능을 활용하지 않을 때 Kotlin에서 "코드 냄새"를 개발하는 경향이 있다는 것입니다.
이 글에서는 제가 자주 접하는 코드 냄새와 이를 "Kotlin 방식"으로 이상적으로 구현하는 방법에 대한 아이디어를 제공합니다.
이 시리즈의 1부 내용은 다음과 같습니다.
이 주제는 점점 더 많은 Java 개발자가 레코드 클래스 사용 경험을 갖게 되면서 곧 사라질 수 있습니다. 그러나 Java 레코드와 Kotlin 데이터 클래스 간에는 몇 가지 차이점이 있습니다.
Java 방식:
<code class="language-java">public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // Getters, setters, ... }</code>
또는 참고로:
<code class="language-java">public record Person( String name, int age ) { }</code>
Kotlin 방식:
<code class="language-kotlin">data class Person(val name: String, var age: Int)</code>
Java 레코드와 Kotlin 데이터 클래스 간에는 알아두면 좋은 몇 가지 차이점이 있습니다.
몇 가지 예:
Java에서 객체 복사
<code class="language-java">Person p2 = new Person(p1.getName(), p1.getAge());</code>
코틀린:
<code class="language-kotlin">val p2 = p1.copy(age = 42)</code>
또는 Java의 구조 분해 선언:
<code class="language-java">String name = p1.getName(); int age = p1.getAge();</code>
코틀린:
<code class="language-kotlin">val (name, age) = p1 println(name) // "John" println(age) // 42</code>
제 생각에는 Kotlin의 null 안전성은 가장 강력한 기능 중 하나입니다. 이는 많은 시간과 번거로움을 줄여줄 획기적인 기능입니다. Kotlin에서는 null 안전성이 유형 시스템에 내장되어 있어 null 관련 런타임 오류를 더 쉽게 방지할 수 있습니다.
Kotlin에서는 null 허용 유형이 명시적으로 선언됩니다. 이는 null 값을 보유할 수 있는 변수가 있을 수 있지만 선언에서 이를 명시적으로 지정해야 함을 의미합니다.
null을 허용하지 않는 유형(기본 동작)
기본적으로 Kotlin의 모든 유형은 null을 허용하지 않습니다. 즉, 변수는 null 값을 가질 수 없습니다.
<code class="language-kotlin">val name: String = "John" // 不可空 name = null // 编译错误!</code>
널 입력 가능 유형
Null 값을 보유할 수 있는 변수를 선언하려면 ? 연산자를 사용해야 합니다.
<code class="language-kotlin">val name: String? = null // 可空</code>
강력한 기능은 안심통화 교환원?. 이를 통해 NullPointerException을 발생시키지 않고 메서드를 안전하게 호출하거나 속성에 액세스할 수 있습니다.
예
<code class="language-java">public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // Getters, setters, ... }</code>
?.operator는 객체가 비어 있는지 확인하고, 비어 있으면 즉시 null을 반환하고, 그렇지 않으면 계속해서 메서드를 호출하거나 속성에 액세스합니다. 객체가 비어 있으면 전체 표현식이 null로 평가됩니다.
엘비스 연산자?: 연산자 왼쪽의 식이 비어 있는 경우 기본값을 반환한다는 뜻의 약어입니다.
<code class="language-java">public record Person( String name, int age ) { }</code>
!! 연산자를 사용하여 값이 null이 아님을 컴파일러에 알릴 수 있습니다. 값이 null이면 NullPointerException이 발생합니다.
<code class="language-kotlin">data class Person(val name: String, var age: Int)</code>
팁: 이 !! 연산자는 널 안전의 목적을 무너뜨리므로 더 이상 사용되지 않습니다.
함수를 정의할 때 매개변수가 null일 수 있는지 여부를 지정할 수 있습니다. 이 경우 호출자가 이를 처리해야 합니다.
<code class="language-java">Person p2 = new Person(p1.getName(), p1.getAge());</code>
변환이 불가능할 경우 null을 반환하는 안전한 변환 연산자 as?가 있습니다.
<code class="language-kotlin">val p2 = p1.copy(age = 42)</code>
람다 표현식과 고차 함수에서 null 안전 기능을 사용할 수도 있습니다.
<code class="language-java">String name = p1.getName(); int age = p1.getAge();</code>
let 함수는 null이 아닌 객체에서 코드 블록을 실행할 수 있는 범위 함수입니다. 일반적으로 null 허용 개체에 대한 코드를 안전한 방식으로 실행하는 데 사용됩니다.
예시 및 기본값:
<code class="language-kotlin">val (name, age) = p1 println(name) // "John" println(age) // 42</code>
Kotlin은 함수형 프로그래밍 스타일을 강력히 권장합니다! 함수형 프로그래밍 스타일의 경우 불변성은 특히 멀티스레드 애플리케이션에서 오류를 방지하는 데 중요한 역할을 합니다.
지금은 Kotlin이나 Java의 함수형 프로그래밍에 관해 별도의 기사를 쓰겠지만 지금은 불변성에 중점을 두겠습니다.
Kotlin은 본질적으로 변경 가능한 객체보다 불변 객체를 선호합니다. 이로 인해 특히 동시 환경에서 더 간단하고 예측 가능한 코드가 생성됩니다.
Kotlin에서는 val 키워드를 사용하여 선언된 변수는 기본적으로 변경할 수 없습니다. 이는 Java에서 최종 변수를 선언하는 것과 매우 유사하지만 몇 가지 주요 차이점이 있습니다.
예:
<code class="language-kotlin">val name: String = "John" // 不可空 name = null // 编译错误!</code>
Java와의 차이점: Java에서는 final 키워드를 사용하여 변수를 다시 할당할 수 없지만 변수가 가리키는 객체는 여전히 변경 가능하다는 것을 보장합니다. Kotlin의 주요 차이점은 불변성이 기본적으로 변수로 확장되어 전체 애플리케이션에 대해 보다 예측 가능하고 안전한 설계를 장려한다는 것입니다.
변수 변수 예: Kotlin에서 var 키워드를 사용하면 변수를 재할당할 수 있습니다.
<code class="language-java">public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // Getters, setters, ... }</code>
팁: Kotlin은 불변성을 보장하기 위해 가능할 때마다 var 대신 val을 사용하도록 권장합니다.
변경 불가능한 컬렉션도 기본적으로 권장됩니다. 불변 컬렉션은 생성 후 수정을 방지합니다. 예를 들어 listOf()를 사용하여 목록을 생성하는 경우 변경할 수 없으며 요소를 추가, 제거 또는 변경할 수 없습니다.
<code class="language-java">public record Person( String name, int age ) { }</code>
컬렉션을 수정해야 하는 경우 mutableListOf() 또는 기타 변경 가능한 컬렉션 유형을 사용할 수 있습니다.
<code class="language-kotlin">data class Person(val name: String, var age: Int)</code>
Java와의 차이점: Java에서는 컬렉션(예: ArrayList)이 기본적으로 변경 가능합니다. 즉, 요소를 자유롭게 수정할 수 있습니다.
Kotlin의 데이터 클래스는 기본적으로 변경할 수 없습니다. 데이터 클래스를 정의할 때 속성은 일반적으로 val로 선언되어 클래스를 변경할 수 없게 만듭니다. 따라서 클래스는 특히 API, 데이터베이스 레코드 또는 생성 후 개체 상태가 변경되어서는 안 되는 기타 시나리오를 처리할 때 값 개체에 이상적입니다.
<code class="language-java">Person p2 = new Person(p1.getName(), p1.getAge());</code>
<code class="language-kotlin">val p2 = p1.copy(age = 42)</code>
Kotlin의 봉인 클래스도 불변일 수 있으며 불변 데이터 모델과 잘 작동합니다. 봉인 클래스는 상태나 응답과 같은 제한된 클래스 계층 구조를 나타내는 데 자주 사용되며, 해당 클래스의 불변성은 상태나 결과가 예기치 않게 변경될 수 없도록 보장합니다.
<code class="language-java">String name = p1.getName(); int age = p1.getAge();</code>
위 내용은 Java 개발자를 위한 Kotlin(1부)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!