-
TECHIT 앱 스쿨 2기: Android 13일차 (23.05.11)[THEC!T] 앱 스쿨2기 : Android 2023. 5. 11. 20:38728x90
자료 출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 내용
오늘 부터는 Kotlin을 배우기 시작하였습니다.
일단 자바를 배우고 나서 코틀린을 다시 배우니 과거 혼자 독학을 하면서 이해가 잘 안되었던 부분들이 더욱 순조롭게 이해가 되는 기분이였습니다.
시작은 코틀린에 대한 배경부터 시작하였었습니다.
매우 요약 하자면 안드로이드는 기존에 자바로 제작된 많은 프로그램들이 있었기에 코틀린을 공식언어로 채택하였지만, 자바와 코틀린 둘 다 지원을 하며, 코틀린은 자바와의 상호 운용성(interoperability)을 강조하면서도 몇 가지 기능적인 개선을 제공합니다. 이 언어는 널 안정성(null safety), 확장 함수(extension function), 데이터 클래스(data class), 함수형 프로그래밍 지원 등과 같은 현대적인 기능을 제공하여 개발자가 코드를 더 간결하고 안전하게 작성할 수 있도록 도와줍니다. 또한, 코틀린은 함수형 프로그래밍과 객체지향 프로그래밍을 모두 지원하므로 개발자가 다양한 프로그래밍 스타일을 선택할 수 있습니다.
그리고 코틀린에 대한 기본 문법에 대해서 학습하면서 자바에서는 어떻게 구현되었는지 비교하며 확인하였습니다.
하기의 자바 코드는 디컴파일된 코드이며, 연관된 부분만을 기재 하도록 하겠습니다.
시작은 프로그래밍 언어를 배울 때 국룰인 Hello World 출력하기 입니다.
fun main(){ println("Hello World") println("안녕하세요") }
디컴파일된 자바 코드
public final class MainKt { public static final void main() { String var0 = "Hello World"; System.out.println(var0); var0 = "안녕하세요"; System.out.println(var0); } // $FF: synthetic method public static void main(String[] var0) { main(); } }
출력결과
Hello World 안녕하세요
위 두 코드를 비교해보면 코틀린을 작성하면 자바코드로 변경되는데, 코틀린 내에서는 fun으로만 작성하였지만 자바코드에서는 코틀린 파일을 생성할 때 지정한 이름의 클래스가 생성되고, 작성한 fun이 멤버 메서드로 구현되는 점을 확인 할 수 있습니다.
다음으로는 주석과 기본 출력문에 대해서 확인하였습니다.
주석은 자바의 문법과 동일합니다.
자바에서는 print,printf,println 을 지원하지만 코틀린에서는 print,println 만을 지원합니다.
가장 편한 점은 앞에 System.out 를 적지 않아도 된다는 점 입니다.
다음으로는 ; 세미콜론을 찍지 않아도 된다는 점 입니다. 한줄의 여러개의 명령문을 작성하지 않는 이상....
fun main(){ // Kotlin에서 주석을 사용하면 // Java 코드로 만들어 질 때 빠진다. // 한 줄 주석 입니다. /* 여러줄 주석 입니다. */ // 기본 출력 // 출력 후 밑으로 내려준다. // System.out.println 으로 변경된다. println("문자열 입니다.") println("문자열 일껄요") println("문자열 이에용") print("문자열 입니다.") print("문자열 일껄요") print("문자열 이에용") println() println("값 : " + 100) // ${} 부분의 값을 추출하여 하나의 문자열로 // 만들어준다. println("값 : ${100}") // 세미콜론 // Java는 명령문 마지막에 세미콜론(;)을 반드시 // 붙혀줘야 하지만 Kotlin은 생략해도 된다. println("세미콜론 없음") println("세미콜론 있음"); // 한 줄에 여러 명령문을 작성한다면 세미콜론으로 // 구분해줘야 한다. print("명령어1"); print("명령어2"); print("명령어3") }
디컴파일된 자바 코드
import kotlin.Metadata; public final class MainKt { public static final void main() { String var0 = "문자열 입니다."; System.out.println(var0); var0 = "문자열 일껄요"; System.out.println(var0); var0 = "문자열 이에용"; System.out.println(var0); var0 = "문자열 입니다."; System.out.print(var0); var0 = "문자열 일껄요"; System.out.print(var0); var0 = "문자열 이에용"; System.out.print(var0); System.out.println(); var0 = "값 : 100"; System.out.println(var0); var0 = "값 : 100"; System.out.println(var0); var0 = "세미콜론 없음"; System.out.println(var0); var0 = "세미콜론 있음"; System.out.println(var0); var0 = "명령어1"; System.out.print(var0); var0 = "명령어2"; System.out.print(var0); var0 = "명령어3"; System.out.print(var0); } // $FF: synthetic method public static void main(String[] var0) { main(); } }
출력결과
문자열 입니다. 문자열 일껄요 문자열 이에용 문자열 입니다.문자열 일껄요문자열 이에용 값 : 100 값 : 100 세미콜론 없음 세미콜론 있음 명령어1명령어2명령어
디컴파일 된 자바파일에서 보면 print문에 있는 문자열을 객체로 생성하여 값을 변경하면서 출력하는 것을 볼 수 있습니다.
다음 으로는 리터럴에 대해서 학습하였습니다.
사실 자바와 큰 차이가 없지만 가장 큰 차이점은 RawString 이며 해당 리터럴은 여러 줄의 문자열을 표현할 때 사용합니다. 사용법은 """내용""" 입니다. 큰 따옴표를 시작과 끝에 3번을 작성하는 것입니다.
| 와 .trinMargin() 은 내용을 작성하다가 엔터키를 눌러 줄을 바꾸면 자동으로 생성이 됩니다.
fun main() { // 정수 리터럴 println(100) // 4 byte 기억공간에 담을 만큼의 값이면 // 뒤에 L을 안붙히고 범위를 넘어가면 // L을 붙혀준다. println(10000000000) println(938_492_934_823) // 실수 println(11.11) println(11.11F) // 문자리터럴 println('A') println('가') // 문자열 리터럴 println("문자열") // 논리타입 println(true) println(false) // RawString // 여러 줄의 문자열을 표현할 때 사용한다. println("동해물과 백두산이\n마르고 닳도록\n하느님이 보우하사\n우리나라 만세") println("-----------------------------------------") println( """동해물과 백두산이 |마르고 닭도록 |하느님이 보우하사 |우리나라 만세 """.trimMargin() ) }
디컴파일된 자바 코드
public final class MainKt { public static final void main() { char var0 = 'd'; System.out.println(var0); long var2 = 10000000000L; System.out.println(var2); var2 = 938492934823L; System.out.println(var2); double var3 = 11.11; System.out.println(var3); float var4 = 11.11F; System.out.println(var4); var0 = 'A'; System.out.println(var0); var0 = '가'; System.out.println(var0); String var5 = "문자열"; System.out.println(var5); boolean var6 = true; System.out.println(var6); var6 = false; System.out.println(var6); var5 = "동해물과 백두산이\n마르고 닳도록\n하느님이 보우하사\n우리나라 만세"; System.out.println(var5); var5 = "-----------------------------------------"; System.out.println(var5); var5 = "동해물과 백두산이\n마르고 닭도록\n하느님이 보우하사\n우리나라 만세"; System.out.println(var5); } // $FF: synthetic method public static void main(String[] var0) { main(); } }
출력 코드
100 10000000000 938492934823 11.11 11.11 A 가 문자열 true false 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라 만세 ----------------------------------------- 동해물과 백두산이 마르고 닭도록 하느님이 보우하사 우리나라 만세
다음은 변수 선언에 대해서 학습하였습니다.
자바에서는 자료형들을 WarpperClass 를 이용하여 객체화를 시켰지만 코틀린은 자료형 자체가 WarpperClass 입니다.
즉 변수을 선언한다면 해당 변수는 선언한 값을 가진 객체가 된다는 말 입니다.
코틀린에서 변수를 선언하는 방법은 2가지가 있습니다.
var 변수명 : 클래스명(자료형) = 값
val 변수명 : 클래스명(자료형) = 값
위의 차이는 값을 변경할 수 있는냐 없는냐 차이 입니다.
var로 선언을 하였다면 해당 변수에 값을 갱신할 수 있지만, val로 선언을 하였다면 변수에 값을 갱신할 수 없습니다.
자바의 final 역할과 동일하다고 생각하시면 됩니다.
그리고 개발자가 매우 편하게 바뀐 점은 자료형을 명시하지 않아도 변수를 선언할 때 값을 같이 넣어 준다면,
자료형을 알아서 추론하여 생성합니다.
또한 print문 이나 println문을 사용할 때 변수의 값을 넣어주고 싶을 때는 $변수명 을 적어주면 됩니다.
fun main() { // 변수 // var/val 변수명:클래스타입 // 변수를 선언할 때 값을 지정해야 한다. var a1: Int = 100 //println("a1 : ${a1}") // ${} 안에 변수를 작성할 때는 {} 를 생략해도 된다. println("a1 : $a1") // 변수를선언할 때 저장할 값을 지정해주면 클래스타입을 생략해도 된다. var a2 = 200 var a3 = 11.11 println("a2 : $a2") println("a3 : $a3") // var : 변수에 값을 계속 저장할 수 있다. // val : 선언시 변수에 값을 저장하고 그 이후에는 값을 저장할 수 없다. var a4 = 100 val a5 = 100 println("a4 : $a4") println("a5 : $a5") a4 = 200 println("a4 : $a4") // val 변수에는 값을 다시 저장할 수 없다. // a5 = 200 // println("a5 : $a5") }
디컴파일된 자바 코드
public final class MainKt { public static final void main() { int a1 = 100; String var1 = "a1 : " + a1; System.out.println(var1); int a2 = 200; double a3 = 11.11; String var4 = "a2 : " + a2; System.out.println(var4); var4 = "a3 : " + a3; System.out.println(var4); int a4 = 100; int a5 = 100; String var6 = "a4 : " + a4; System.out.println(var6); var6 = "a5 : " + a5; System.out.println(var6); a4 = 200; var6 = "a4 : " + a4; System.out.println(var6); } // $FF: synthetic method public static void main(String[] var0) { main(); } }
출력결과
a1 : 100 a2 : 200 a3 : 11.11 a4 : 100 a5 : 100 a4 : 200
디컴파일된 자바코드에서는 final을 선언하지 않았지만 값을 val로 선언된 변수는 값을 변경할 수 없습니다.
그리고 변수를 선언하면서 자바와 코틀린 중 가장 큰 차이이며, 코틀린의 특징 중 하나인 Null 안정성 이라는 특징을 배웠습니다.
자바에서는 변수를 선언할 때 null을 제한 없이 넣을 수 있지만, 코틀린의 경우 다릅니다.
즉 변수 생성 및 변경에 있어 해당 변수에 null값을 저장하지 못하도록 강제할 수 있습니다.
만약 변수에 null 값을 넣는 것을 허용하고 싶다면 자료형 뒤에 ?를 붙혀서 null 값을 담을 수 있는 객체를 생성할 수 있습니다.
그리고 null을 허용하지 않는 변수에 null을 저장할 경우 Kotlin: Null can not be a value of a non-null type Int 이라는 에러가 발생합니다. 즉 프로그램이 실행되지 않고 컴파일 단계에서 다 걸립니다.
또한 null을 허용하지 않는 변수에 null을 허용하는 변수를 넣는 경우 마찬가지입니다.
NullPointerException 에러가 발생하게 됩니다.
이렇게 코틀린은 컴파일 단계에서 사용하는 null을 허용하지 않는 변수가 null일 가능성이 있다면 프로그램을 실행하지 않습니다.
만약 null을 허용하는 변수를 null을 허용하지 않는 변수로 변환하고자 한다면 null을 허용하는 변수명 뒤에 !!을 작성하면 됩니다. 이때 null을 허용하는 변수는 값을 지정해줘야 합니다. 하지 않을 경우 NullPointerException 에러가 발생합니다.
fun main() { // ? 변수 // Kotlin 특징 중에 Null 안정성이라는 부분이 있다. // 참조 변수에 객체의 ID가 있다면 그 객체에 접근할 수 있지만 // null이 있다면 객체의 ID가 없으므로 객체에 접근할 수 없다. // null이 있는 상태에서 개발자가 객체에 접근하는 코드를 작성해 실행하면 // NullPointerException이 발생한다. // 이에, 코틀린에서는 변수에 아예 null을 저장하지 못하게 하여 반드시 // 변수에 객체의 ID를 담도록 강제할 수 있다. // 변수 뒤에 ?를 붙히지 않으면 null 값을 담을 수 없다. // 반드시 객체의 ID를 넣어줘야 한다. //var a6 : Int = null // 변수 뒤에 ? 를 붙히면 null 값을 담을 수 있다. var a7 : Int? = null println("a7 : $a7") a7 = 100 println("a7 : $a7") // null을 허용하지 않는 변수에 null을 허용하는 변수의 값을 저장한다 // !! : null을 허용하는 값의 타입을 null을 허용하지 않는 타입으로 변환한다. var a8:Int = a7!! println("a8 : $a8") // 상기 코드 보다는 하기 코드 추천. // 지금은 a7에 값을 저장하였지만 만약 코드가 복잡할 경우 // a7에 값이 저장되어있을 거라는 보증이 없기 때문에 if(a7 != null){ var a8:Int = a7 println("a8 : $a8") } }
디컴파일된 자바 코드
public final class MainKt { public static final void main() { Integer a7 = null; String var1 = "a7 : " + a7; System.out.println(var1); a7 = 100; var1 = "a7 : " + a7; System.out.println(var1); int a8 = a7; String var2 = "a8 : " + a8; System.out.println(var2); int a8 = a7; String var3 = "a8 : " + a8; System.out.println(var3); } // $FF: synthetic method public static void main(String[] var0) { main(); } }
a7 : null a7 : 100 a8 : 100 a8 : 100
다음은 코틀린 함수에 대해서 배웠습니다.
자바에서는 메서드라고 부르는데 이 메서드는 클래스 안에 있어야 하지만 코틀린의 경우 클래스 안에 작성하지 않아도 됩니다. 왜냐하면 자바로 변경될 때 코틀린 파일을 생성할 때 지정한 명과 동일한 클래스 안에 들어가기 때문입니다.
즉 자바로 변환되면서 메서드가 됩니다.
코틀린에서 함수를 호출할 때는 간단하게 함수명() 이렇게 적어주면 호출은 끝납니다.
만약 매개변수가 있다면 () 안에 함수에 동일한 자료형의 매개변수를 넣어주면 됩니다.
그리고 함수의 오버로딩이 가능합니다.
오버로딩이란 같은 이름이지만 매개변수의 개수나 타입을 다르게 하여 같은 이름의 함수를 여러개를 만드는 것을 의미합니다.
함수의 작성형태는 fun 함수명(매개 변수:타입) : 반환타입{내용} 이러한 형태로 적어주면 됩니다.
함수의 매개변수에는 타입을 생략할 수 없습니다.
만약 반환 타입 없다면 Unit을 적어줘도 되고, 생략을 해도 가능합니다.
그리고 함수 내 기본 값이 있을 경우 () 안에 매개변수를 지정하여 값을 셋팅 할 수 있습니다.
매개 변수를 지정하여 값을 전달해 주면 전달 받은 값을 우선으로 합니다.
fun main(){ test(a=10) test(b=20) test(a = 30, b = 40) } fun test(a: Int = 1, b:Int = 2) : Int{ return a+b }
출력 결과
a = 10 b = 2 a = 1 b = 20 a = 30 b = 40
코틀린 코드
fun main(){ // 함수 호출 test1() // 매개변수를 가지고 있는 함수 호출 test2(100, 11.11) // 값을 부족하게... 오류발생 //test2(100) // 값을 더 많게... 오류발생 //test2(100,200, 300) // 함수를 호출할 때 넘겨주는 값을 어떤 매개변수에 담을지 정할 수 있다. test2(a2 = 22.22, a1 = 200) // 기본값을 가지고 있는 함수 호출 test3(100,200) test3(100) test3() test3(a2 = 200) // 반환값이 있는 메서드 호출 var r1 = test4(100,200) println("r1 : $r1") // 반환값이 없는 함수 호출 test5() test6() // overloading 개념을 적용하여 만든 함수들 호출 test7() test7(100) test7(11.11) test7(100,100) // 지역함수를 가진 함수 호출 test8() // test8 내부에 만든 지역함수를 호출 // 지역함수는 지역함수를 가지고 이쓰는 함수 내부에서만 사용이 가능하다. //test8 } // 함수 밖에 변수를 선언한다. // 함수 밖에 선언된 변수는 파일이름클래스의 static 변수로 정의된다. var a1 : Int = 100 // 기본함수 // fun 함수이름(매개변수) : 반환타입 // Java 코드로 변경되면 파일이름클래스 내부의 static 메서드로 정의된다. fun test1(){ println("test1 호출") // 함수 밖에서 선언된 변수 사용 println("a1 : $a1") println("----------------------") } // 함수의 매개변수 // 함수의 매개변수는 타입을 생략할 수 없다. fun test2(a1: Int,a2: Double){ println("test2 호출") println("a1 : $a1") println("a2 : $a2") } // 기본값을 가지고 있는 매개변수 // 함수를 호출할 때 매개변수에 들어갈 값을 지정하지 않으면 // 기본값이 매개변수가 저장된다. fun test3(a1:Int = 1, a2:Int = 2){ println("test3 호출") println("a1 : $a1") println("a2 : $a2") } // 반환타입 // 매개변수 뒤에 반환할 값의 타입을 작성해준다 fun test4(a1:Int, a2:Int) : Int{ return a1+a2 } // 반환 값이 없는 하무수의 경우 반환 타입에 Unit를 작성한다. fun test5() : Unit{ println("test5 함수 호출") } // Unit은 생략해도 된다. fun test6() { println("test6 함수 호출") } // Overloading : 매개변수의 형태(개수, 타입)을 다르게 하여 // 같은 이름의 함수를 다수 만들 수 있는 개념 fun test7(){ println("test7 호출 - 매개변수 없음") } fun test7(a1:Int){ println("test7 호출 - a1 : $a1") } fun test7(a1:Double){ println("test7 호출 - a1 : $a1") } fun test7(a1:Int, a2:Int){ println("test7 호출 - a1 : $a1, a2 : $a2") } // 지역 함수 // 함수 내부에 만든 함수 로써 함수 내부에서만 사용이 가능하다. fun test8(){ println("test8 호출") fun test9(){ println("test9 호출") } // 지역함수 호출 test9() }
디컴파일 된 자바 코드
public final class MainKt { private static int a1 = 100; public static final void main() { test1(); test2(100, 11.11); int r1 = 200; double var1 = 22.22; test2(r1, var1); test3(100, 200); test3$default(100, 0, 2, (Object)null); test3$default(0, 0, 3, (Object)null); test3$default(0, 200, 1, (Object)null); r1 = test4(100, 200); String var3 = "r1 : " + r1; System.out.println(var3); test5(); test6(); test7(); test7(100); test7(11.11); test7(100, 100); test8(); } // $FF: synthetic method public static void main(String[] var0) { main(); } public static final int getA1() { return a1; } public static final void setA1(int var0) { a1 = var0; } public static final void test1() { String var0 = "test1 호출"; System.out.println(var0); var0 = "a1 : " + a1; System.out.println(var0); var0 = "----------------------"; System.out.println(var0); } public static final void test2(int a1, double a2) { String var3 = "test2 호출"; System.out.println(var3); var3 = "a1 : " + a1; System.out.println(var3); var3 = "a2 : " + a2; System.out.println(var3); } public static final void test3(int a1, int a2) { String var2 = "test3 호출"; System.out.println(var2); var2 = "a1 : " + a1; System.out.println(var2); var2 = "a2 : " + a2; System.out.println(var2); } // $FF: synthetic method public static void test3$default(int var0, int var1, int var2, Object var3) { if ((var2 & 1) != 0) { var0 = 1; } if ((var2 & 2) != 0) { var1 = 2; } test3(var0, var1); } public static final int test4(int a1, int a2) { return a1 + a2; } public static final void test5() { String var0 = "test5 함수 호출"; System.out.println(var0); } public static final void test6() { String var0 = "test6 함수 호출"; System.out.println(var0); } public static final void test7() { String var0 = "test7 호출 - 매개변수 없음"; System.out.println(var0); } public static final void test7(int a1) { String var1 = "test7 호출 - a1 : " + a1; System.out.println(var1); } public static final void test7(double a1) { String var2 = "test7 호출 - a1 : " + a1; System.out.println(var2); } public static final void test7(int a1, int a2) { String var2 = "test7 호출 - a1 : " + a1 + ", a2 : " + a2; System.out.println(var2); } public static final void test8() { String var0 = "test8 호출"; System.out.println(var0); <undefinedtype> $fun$test9$1 = null.INSTANCE; $fun$test9$1.invoke(); } }
조건문 중 if문은 자바와 동일한 기능을 합니다.
차이점이라고 한다면 변수의 값을 지정할 때 if문을 사용하여 작성할 수 있다는 점입니다.
fun main(){ val a1 = 5 val a2 = if(a1 == 5) "참" else "거짓" println(a2) val a3 = if(a1 == 10){ println("a1은 10이다.") "10" } else { println("a1은 10이 아니다.") "10 X" } println(a3) }
출력 결과
참 a1은 10이 아니다. 10 X
그리고 코틀린은 switch문 대신 when문을 지원합니다.
fun main(){ val a1 = 10 when(a1){ // 수행될 코드가 한줄만 있다면 { }를 생략한다. 1 -> println("a1은 1 입니다.") // 수행될 코드가 두 줄 이상이면 { }로 묶어준다. 5 -> { println("a1은 5 입니다.") println("코드가 두 줄") println("코드가 세 줄") } 10 -> println("a1은 10 입니다.") else -> println("a1은 1, 5, 10이 아닙니다.") } // 두 가지 이상의 조건을 만족하는 것도 설정이 가능하다. val a2 = 3 when(a2){ 1, 2 -> println("a2는 1 이거나 2 입니다.") 3, 4 -> println("a2는 3 이거나 4 입니다.") 5, 6 -> println("a2는 5 이거나 6 입니다.") else -> println("a2는 1, 2, 3, 4, 5, 6이 아닙니다.") } // 실수도 가능하다. val a3 = 55.55 when(a3){ 33.33 -> println("a3은 33.33 입니다.") 55.55 -> println("a3은 55.55 입니다.") 77.77 -> println("a3은 77.77 입니다.") else -> println("a3은 33.33, 55.55, 77.77 이 아닙니다.") } // 문자열 val a4 = "문자열2" when(a4){ "문자열1" -> println("첫 번째 문자열 입니다.") "문자열2" -> println("두 번째 문자열 입니다.") "문자열3" -> println("세 번째 문자열 입니다.") else -> println("else 문자열 입니다.") } // 논리값 // 논리값은 허용되지 않는다. // val a5 = true // when(a5){ // // } // 범위 지정 val a5 = 5 when(a5){ in 1 .. 3 -> println("a5는 1부터 3 사이 입니다.") in 4 .. 6 -> println("a5는 4부터 6 사이 입니다.") in 1 .. 6 -> println("a5는 1부터 6 사이 입니다.") else -> println("a5는 1 ~ 6사이의 숫자가 아닙니다.") } val str1 = setValue1(1) val str2 = setValue1(2) val str3 = setValue1(3) println("str1 : $str1") println("str2 : $str2") println("str3 : $str3") val str4 = setValue2(1) val str5 = setValue2(2) val str6 = setValue2(3) println("str4 : $str4") println("str5 : $str5") println("str6 : $str6") } fun setValue1(a1:Int): String{ if(a1 == 1){ return "문자열" } else if(a1 == 2){ println("두 번째 경우의 수") return "문자열2" } else { return "그 외의 문자열" } } // when 사용 // when에 설정한 변수의 값에 따라서 해당 부분에 제일 마지막에 작성한 // 값을 반환한다. fun setValue2(a1: Int) = when(a1){ 1 -> "문자열1" 2 -> { println("두 번째 경우의 수") "문자열2" } else -> "그 외의 문자열" }
디컴파일된 자바 코드
public final class MainKt { public static final void main() { int a1 = 10; String var1; switch (a1) { case 1: var1 = "a1은 1 입니다."; System.out.println(var1); break; case 5: var1 = "a1은 5 입니다."; System.out.println(var1); var1 = "코드가 두 줄"; System.out.println(var1); var1 = "코드가 세 줄"; System.out.println(var1); break; case 10: var1 = "a1은 10 입니다."; System.out.println(var1); break; default: var1 = "a1은 1, 5, 10이 아닙니다."; System.out.println(var1); } int a2 = 3; String var2; switch (a2) { case 1: case 2: var2 = "a2는 1 이거나 2 입니다."; System.out.println(var2); break; case 3: case 4: var2 = "a2는 3 이거나 4 입니다."; System.out.println(var2); break; case 5: case 6: var2 = "a2는 5 이거나 6 입니다."; System.out.println(var2); break; default: var2 = "a2는 1, 2, 3, 4, 5, 6이 아닙니다."; System.out.println(var2); } double a3 = 55.55; String str1; if (a3 == 33.33) { str1 = "a3은 33.33 입니다."; System.out.println(str1); } else if (a3 == 55.55) { str1 = "a3은 55.55 입니다."; System.out.println(str1); } else if (a3 == 77.77) { str1 = "a3은 77.77 입니다."; System.out.println(str1); } else { str1 = "a3은 33.33, 55.55, 77.77 이 아닙니다."; System.out.println(str1); } label46: { switch (a4) { case "문자열1": str1 = "첫 번째 문자열 입니다."; System.out.println(str1); break label46; case "문자열2": str1 = "두 번째 문자열 입니다."; System.out.println(str1); break label46; case "문자열3": str1 = "세 번째 문자열 입니다."; System.out.println(str1); break label46; } str1 = "else 문자열 입니다."; System.out.println(str1); } int a5 = true; String str2 = "a5는 4부터 6 사이 입니다."; System.out.println(str2); str1 = setValue1(1); str2 = setValue1(2); String str3 = setValue1(3); String str4 = "str1 : " + str1; System.out.println(str4); str4 = "str2 : " + str2; System.out.println(str4); str4 = "str3 : " + str3; System.out.println(str4); str4 = setValue2(1); String str5 = setValue2(2); String str6 = setValue2(3); String var12 = "str4 : " + str4; System.out.println(var12); var12 = "str5 : " + str5; System.out.println(var12); var12 = "str6 : " + str6; System.out.println(var12); } // $FF: synthetic method public static void main(String[] var0) { main(); } @NotNull public static final String setValue1(int a1) { if (a1 == 1) { return "문자열"; } else if (a1 == 2) { String var1 = "두 번째 경우의 수"; System.out.println(var1); return "문자열2"; } else { return "그 외의 문자열"; } } @NotNull public static final String setValue2(int a1) { String var10000; switch (a1) { case 1: var10000 = "문자열1"; break; case 2: String var1 = "두 번째 경우의 수"; System.out.println(var1); var10000 = "문자열2"; break; default: var10000 = "그 외의 문자열"; } return var10000; } }
위에서 보면 코틀린 코드 중 1 .. 3 이렇게 되어 있는 부분이 있는데 이 것은
1 ~ 3 즉 1부터 3까지 라는 의미 입니다.
그리고 마지막으로 반복문입니다.
while문과 do ~ while문은 자바와 동일 하므로 생략하도록 하겠습니다.
기존 자바에서 for문을 작성할 때 for(int i = 0; i < 10; i++) 이렇게 작성하였다면
코틀린에서는 for(i in 1 .. 10) 으로 작성합니다.
하기는 2씩 증가 및 감소 등 반복문 입니다.
코틀린 코드
fun main(){ // 1 ~ 10까지 총 10번 반복을 하고 // 반복할 때 마다 반복 회차에 해당하는 값을 in 좌측 변수에 담아준다. // 이때, 변수는 타입을 정하지 않아도 된다. for(item1 in 1 .. 10){ println("item1 : $item1") } println("---------------------------------------") // 2씩 증가 시키는 경우 for(item2 in 1 .. 10 step 2){ println("item2 : $item2") } println("---------------------------------------") // 10 부터 감소... for(item3 in 10 downTo 1 ){ println("item3 : $item3") } println("---------------------------------------") // 10 부터 2씩 감소 for(item4 in 10 downTo 1 step 2){ println("item4 : $item4") } println("---------------------------------------") // while // 자바와 동일하다 var a5 = 0 while(a5 < 10){ println("while : $a5") a5++ } println("---------------------------------------") // do while // 자바랑 동일하다 var a6 = 0 do{ println("do while : $a6") a6++ }while(a6 < 10) }
디컴파일 된 자바 코드
public final class MainKt { public static final void main() { int a5 = 1; int a6; String var2; for(a6 = 10; a5 <= a6; ++a5) { var2 = "item1 : " + a5; System.out.println(var2); } IntProgression var10000; String var4; int var6; String var8; label61: { var4 = "---------------------------------------"; System.out.println(var4); byte var3 = 1; var10000 = RangesKt.step((IntProgression)(new IntRange(var3, 10)), 2); a5 = var10000.getFirst(); a6 = var10000.getLast(); var6 = var10000.getStep(); if (var6 >= 0) { if (a5 > a6) { break label61; } } else if (a5 < a6) { break label61; } while(true) { var8 = "item2 : " + a5; System.out.println(var8); if (a5 == a6) { break; } a5 += var6; } } var4 = "---------------------------------------"; System.out.println(var4); a5 = 10; for(byte var5 = 1; a5 >= var5; --a5) { var2 = "item3 : " + a5; System.out.println(var2); } label46: { var4 = "---------------------------------------"; System.out.println(var4); var10000 = RangesKt.step(RangesKt.downTo(10, 1), 2); a5 = var10000.getFirst(); a6 = var10000.getLast(); var6 = var10000.getStep(); if (var6 >= 0) { if (a5 > a6) { break label46; } } else if (a5 < a6) { break label46; } while(true) { var8 = "item4 : " + a5; System.out.println(var8); if (a5 == a6) { break; } a5 += var6; } } var4 = "---------------------------------------"; System.out.println(var4); String var7; for(a5 = 0; a5 < 10; ++a5) { var7 = "while : " + a5; System.out.println(var7); } var7 = "---------------------------------------"; System.out.println(var7); a6 = 0; do { var2 = "do while : " + a6; System.out.println(var2); ++a6; } while(a6 < 10); } // $FF: synthetic method public static void main(String[] var0) { main(); } }
마무리
계속 자바를 배우다 코틀린을 다시 배우면서 하니 처음 독학을 했을 때보다 아 그래서 이렇게 쓰였구나 라는 생각이 들었었습니다. 코틀린을 독학하기 전에 개념등을 좀 더 많이 접하고 배웠다면 좋았을 걸...이라는 생각도 들었습니다.
그리고 코틀린 코드를 작성하면서 저도 모르게 new를 치고 있었던 저를 발견하게 되었습니다.ㅋㅋㅋㅋㅋ
오늘 가장 나름 좋았던 것은 인텔리제이를 약간 야매 방식으로 쓰고 있었는데... 오늘 제대로 쓰는 법을 배웠습니다.ㅋㅋㅋ
오늘의 마음가짐
기본 개념을 잘 쌓고 반복하면서 실력을 키워 나가는 개발자가 되자~!
'[THEC!T] 앱 스쿨2기 : Android' 카테고리의 다른 글
TECHIT 앱 스쿨 2기: Android 15일차 (23.05.15) (0) 2023.05.15 TECHIT 앱 스쿨 2기: Android 14일차 (23.05.12) (0) 2023.05.12 TECHIT 앱 스쿨 2기: Android 12일차 (23.05.10) (0) 2023.05.10 TECHIT 앱 스쿨 2기: Android 11일차 (23.05.09) (0) 2023.05.09 TECHIT 앱 스쿨 2기: Android 10일차 (23.05.08) (0) 2023.05.08