Programming/Kotlin

Kotlin + Spring Boot 기본적인 api를 만들면서 비교한 Java + Spring Boot와의 차이점

Jan92 2023. 6. 2. 22:25

코프링(Kotlin + Spring), 자프링(Java + Spring) 차이점

최근 여러 기업들이 Java + Spring 기반의 백엔드에서 Kotlin + Spring 기술 스택을 도입하고 있으며, 백엔드 개발자들 사이에서도 코프링(Kotlin + Spring)이라는 용어가 생길 정도로 코틀린에 대한 관심도가 증가하고 있는데요.

 

아래 내용은 Kotlin + Spring Boot를 통해 간단한 api(get, post)를 만들면서 비교해 본 Java + Spring Boot와의 차이점에 대한 정리입니다.

 

***

JetBrains에서 만든 JVM 기반의 언어인 코틀린은 자바와의 호환성을 기반으로 생산성을 높이기 위해 나왔으며, 높은 가독성과 자바의 고질적인 문제였던 Null 안전성을 해결하는 것에 초점을 맞춘 언어입니다.

 


1. 하나의 파일(*.kt)에 여러 개의 클래스 정의 가능

KotlinApplication.kt

자바에서는 하나의 java 파일에 최대 1개의 public 클래스를 가질 수 있는 반면, 코틀린에서 kt 파일은 여러 개의 java 파일로 만들어지기 때문에 public 클래스에 대한 제한이 없어지는데요.

 

이처럼 하나의 파일에 여러 개의 클래스가 들어갈 수 있는 이유는 파일이나 폴더를 기준으로 하지 않고 파일 내에 있는 패키지 단위로 구분하기 때문이라고 하며, 때문에 코틀린의 경우 파일명과 클래스명이 일치하지 않아도 된다는 특징이 있습니다.

 

 


2. 변수 선언 및 파라미터 정의 방법

//method
public void post(Message message) {
    service.post(message);
}

//variable declare & initialize
String name = "jan92";

(java method, variable declare & initialize)

 

//method
fun post(message: Message) {
    service.post(message)
}

//variable declare & initialize
val name: String = "jan92"

(kotlin method, variable declare & initialize)

 

java와 kotlin에서 메서드 선언 또는 변수 선언 및 초기화 방식을 살펴보면, 자바의 경우 자료형 다음에 변수명(또는 파라미터명)을 입력하는 반면, 코틀린의 경우 변수명(또는 파라미터명)이 먼저 오고 콜론(:) 기호 뒤에 자료형이 오게 됩니다.

 

 

val variable = "hello"
println(variable::class)        // ::class 객체의 Kotlin 클래스를 확인하는 메서드
println(variable.javaClass)     // .javaClass 객체의 Java 클래스를 확인하는 메서드

//결과
class kotlin.String
class java.lang.String

또한 코틀린은 위 예시와 같이 변수 타입 지정을 생략할 수 있는데요.

변수 타입이 생략되었을 때는 컴파일러가 문백을 고려하여 변수 타입을 자동으로 유추하여 결정하게 되는데, 이것을 타입 추론(type inference)라고 합니다.

 

***

코틀린은 자바와 마찬가지로 정적 타입 지정 언어(statically typed)인데요. 정적 타입 언어는 컴파일 타임에 타입 검증이 일어나며, 프로그램 내부적으로도 객체의 필드나 메서드를 사용할 때마다 컴파일러가 타입을 검증해 줍니다.

 

 


3. 널 안전성(null-safety) & 안전한 호출(safe call)

 

- null safety

var nullable: String? = "nullable"
var nonNull: String = "nonNull"

nullable = null  // 컴파일 성공
nonNull = null   // 컴파일 에러

코틀린은 기존의 자바에서 문제로 여겨졌던 NPE(NullPointerException) 문제를 해결하는 것에 초점을 두고 나왔는데요.

코틀린에서 타입 시스템은 물음표(?) 기호를 통해 null이 가능한 참조와 그렇지 않은 참조를 구분합니다.

변수 선언 시 nullable, nonNull 여부를 무조건 선언해야 하며, 타입 뒤에 (?)가 붙은 타입의 경우 nullable 한 타입이 되고, 붙지 않은 경우 null을 허용하지 않는 nonNull 타입이 됩니다.

 

위 예시와 같이 nonNull 한 타입에 null을 대입하려고 했을 때, 컴파일 시점에서 에러가 발생하게 되는데요. 컴파일 시점에서 에러가 발생하기 때문에 개발을 하면서 발생할 수 있는 NPE를 미리 예방할 수 있게 됩니다.

 

 

- safe call

var name: String? = null
val size = name?.length

println(size)
// null

코틀린에서는 nullable 한 변수에 접근하기 위한 방법으로 안전한 호출 연산자를 사용할 수 있는데요.

안전한 호출 연산자는 위 코드 예시와 같이 (?.) 형태로 사용할 수 있으며, null 체크와 메서드 호출을 한 번의 연산으로 수행합니다.

 

위 name?.length를 java 코드로 보면 if (name != null) { return name; } else { reutn null;} 이 됩니다.

 

 


4. val, var

 

- val

변경 불가능한 immutable 참조를 저장하는 변수로 value(값)의 약자입니다.

val로 선언된 변수는 초기화 이후 재할당이 불가능하며 java의 final 변수와 같다고 볼 수 있습니다.

 

- var

변경 가능한 mutable 참조를 저장하는 변수로 variable(변수)의 약자입니다.

 

코틀린은 불변성을 기본으로 하기 때문에 기본적으로 모든 변수에 대해 val 키워드를 사용하여 immutable 변수로 선언하고 추후에 필요할 때 var로 변경하여 사용한다는 특징이 있습니다.

 

 


5. data class

class Member {
    String name;
    int age;
    
    @Override
    public String toString() { ... }
    
    public String getName() { return name; }
    
    public void setName(String name) { this.name = name; }
    
    ...
}

kotlin에서는 데이터를 다루는 데 최적화된 클래스로 data class를 사용하는데요.

예를 들어 기존에 java에서 사용하던 위와 같은 클래스를 코틀린 data class로 작성했을 때는 아래와 같이 간단하게 사용할 수 있다는 장점이 있습니다.

 

data class Member (val name: String, val age: Int)

코틀린의 data class는 생성자에서 getter(), setter() 그리고 canonical methods까지 자동으로 생성해 주기 때문에 getter, setter 등의 보일러 플레이트 코드를 작성하지 않아도 된다는 장점이 있습니다.

 

*** Canonical Methods

Any에 선언된 메서드 hashCode(), copy(), equals(), toString(), componentsN()

(Any는 java의 Object와 같이 코틀린에서 모든 객체의 조상이 되는 객체입니다.)

 

 


6. fun

코틀린에서 함수 선언은 function의 줄임말인 fun 키워드를 사용하는데요.

함수의 기본 형태는 아래와 같으며, 코틀린에서 함수는 최상위 수준에 정의가 가능하기 때문에 자바와 다르게 클래스 안에 함수를 넣을 필요가 없다는 특징이 있습니다.

 

fun 함수명(변수): Unit { }
fun 함수명(변수): 리턴 타입 { return 값 }
// return 하지 않는 함수(void)의 경우 선언한 리턴 타입 Unit은 생략이 가능합니다.


//example
fun findMessages(): List<Message> = db.findMessages()

fun post(message: Message) { 
    db.save(message) 
}

 

 


7. 세미콜론(;)

코틀린에서 명령문 마지막의 세미콜론(;)은 선택 사항인데요.

한 줄에서 두 개 이상의 표현식이나 명령문을 사용할 경우에만 세미콜론(;)을 꼭 붙여야 합니다.

 

 

 

 

< 참고 자료 >

https://kotlinlang.org/docs/data-classes.html

https://thdev.tech/kotlin/2016/08/04/Kotlin-Null-Safety/

https://readystory.tistory.com/85