
참고 : https://jinjinyang.tistory.com/66
기본 선언
fun sum(a: Int, b: Int):Int = a+b { }
반환 값이 void
fun sum2(a: Int, b: Int):Unit { }
코틀린 함수의 장점 => 매개값이 다른 동일한 함수를 계속 만들 필요 X
var : 변수(가변값)
val myName : String = "ashd"
val : 상수(불변값)
var myAge : Int = 20
$변수
val number = 20
println("Please give me $number dollors")
${수식}
val number = 20
println("I only have ${if (number <10 ) number else 10} dollor")
Java
@Getter
@Setter
@AllArgsConstructor
public class Person {
private String name;
private int age;
private boolean isMarred;
}
Kotlin
class Person(val name: String, val age: Int, val isMarried: Boolean)
fun main (args: Array<String>) {
val person = Person("ashd", 20, false)
println(person.isMarried());
}
### decompile(자바로 어떻게 되는지) => shiftX2(info창) - Bytecode Viewer
public final class PersonKt {
public static final void main() {
Person person = new Person("ashd", 20, false);
String var1 = person.getName();
System.out.println(var1);
int var2 = person.getAge();
System.out.println(var2);
boolean var3 = person.isMarried();
System.out.println(var3);
}
class Rectangle (val height: Int, val width: Int) {
val isSquare:Boolean
get(){
return height == width
}
}
하나의 파일에 여러 클래스와 함수, 최상위 변수를 선언 가능 + 장점
코틀린에서 편리해서 자주 활용되는 부분임
결합도가 높은 클래스, 유사한 클래스, enum 클래스 등 한곳에 모아 놓으면 관리와 사용이 편리해짐
enum class Color(val r: Int, val g: Int, val b: Int){
RED(255, 0, 0),
ORANGE(255, 166, 0),
YELLOW(255, 255, 0),
GREEN(0, 255, 0);// 아래 함수와 구분을 위해서 세미콜론 추가
fun rgb() = (r * 256 + g) *256 + b
}
fun getKoreanColor(color: Color): String =
when(color) {
RED, ORANGE -> "빨강 혹은 오렌지"
YELLOW -> "노랑"
GREEN -> "녹색"
}
}
fun mix(c1: Color, c2: Color) =
//인자가 없는 when의 경우 반드시 else을 정의해야 됨
when {
c1 == RED && c2 == YELLOW -> ORANGE
c1 == YELLOW && c2 == BLUE -> GREEN
else -> throw RuntimeException()
}
fun printObject(obj: Any): Unit = when(obj){
is String -> println(obj.lowercase())
is Duration -> println(obj.nano)
is LocalDateTime -> println(obj.month)
else -> println("Unknown type")
}
fun main(){
for (i in 1..10){
println(evenOrOdd(i))
}
// 마지막 10 미포함 -> until활용
// for (i in 1<= until < 100)
val students = mutableMapOf<Int, String>()
students[1] = "lee"
students[2] = "kim"
students[3] = "park"
일반 mapOf는 to를 통해 key, value 선언 (가장 많이 사용)
val st = mapOf(
1 to "Jock",
2 to "Diana",
3 to "Frost"
)
fun parse(numberStr: String): Int = try {
Integer.parseInt(numberStr)
throw IOException("일부로 발생시키는 checked exception")
} catch (e: IOException) {
throw RuntimeException("UnChecked exception으로 변환") // 후에 설명할 checked Exception 처리 방식
} finally {
println("무조건 실행되는 코드블록")
}
중요 @Transactional과 checked Exception
Checked Exception: 컴파일 타임에 체크되는 예외 = 처리를 해야 코드가 돌아감
Ex) IOException, SQLException, ClassNotFoundException 등
Unchecked Exception: NullPointerException 같은 작동 중에 발생하는 에러
Java에서는 @Transcational을 사용하면 unchecked exception이 발생할 경우에만 트랜잭션을 롤백한다.
= 컴파일 과정에서, reader로 읽을 파일이 존재하는지, 읽기 권한은 있는지 등의 checked Exception이 발생할 수 있는 에러는 찾아서 실행을 막음(이미 걸러짐) => Unchecked Exception이 발생했을 때만 롤백해도 정상적으로 작동
Kotiln에서는 Checked Exception이 없음 즉, @Transcational을 사용하면 checked exception이 발생한 경우 롤백하지 않는다.
= IO Exception과 같은 checked Exception이 발생했을 경우 강제로 unchecked Exception을 던져주거나, 롤백하는 코드가 필요
pstmt1이 실행하는 sql문이 name으로 찾아서 update라면, update가 실패할 가능성 존재
try (PreparedStatement pstmt1 = connection.prepareStatement(sql1);
// 쿼리 실행 (예외 발생 가능성)
pstmt1.setString(1,"Bob");
pstmt1.executeUpdate();
// 모든 쿼리가 성공적으로 실행되면 커밋
connection.commit();
} catch (SQLException e) {
// 예외 발생 시 롤백
System.out.println("예외 발생: " + e.getMessage());
if (connection != null) {
try {
connection.rollback();
System.out.println("트랜잭션 롤백 완료");
} catch (SQLException rollbackEx) {
System.out.println("롤백 중 오류 발생: " + rollbackEx.getMessage());
}
}
}
fun <E> List<E>.getHigherThan(num: E): List<E> {
// 구현....
return arrayListOf<E>()
}
중요 : 확장 함수는 정적 바인딩된다!
open class Idol {
open fun sing() = println("아이돌이 노래를 불러요")
}
class BTS: Idol() {
override fun sing() = println("BTS가 노래를 불러요")
}
fun Idol.dance() = println("아이돌이 춤을 춰요")
fun BTS.dance() = println("BTS가 춤을 춰요")
fun main() {
// 부모 타입으로 자식 객체 생성
val bts: Idol = BTS()
bts.sing() // BTS가 노래를 불러요
bts.dance() // 아이돌이 춤을 춰요
}
타입과 객체 : Idol 타입의 변수인 bts는 Idol 클래스 또는 그 자식 클래스인 BTS의 객체를 참조
var StringBuilder.lastChar: Char
get() = get(length - 1)
set(value: Char) {
this.setCharAt(length - 1, value)
}
fun main() {
val sb = StringBuilder("Gold")
sb.lastChar = 'f'
println(sb) // golf
}
상속 생성자 선언 방법
class Child : Parent{
private val subName:String
constructor(subName: String):this(subName, "")
constructor(subName:String, firstName: String):super(firstName){
this.subName = subName
}
}
위 코드의 간소화
class Child(val subName:String, firstName: String = "") : Parent(firstName)
interface Error
class FileError(val filename:String) : Error
class DatabaseError(val database:Database) : Error
class RedisError(val host:String): Error
enum class Database{
ORACLE, MYSQL, MARIADB;
}
fun getMassage(error: Error) = when(error){
is FileError -> "error is fileError ${error.filename}"
is DatabaseError -> "error is databaseError ${error.database.name}"
else -> throw IllegalArgumentException("error is unknown")
}
sealed class Error2{
class FileError(val filename:String) : Error2()
class DatabaseError(val database:Database) : Error2()
class RedisError(val host:String): Error2()
}
enum class Database2{
ORACLE, MYSQL, MARIADB;
}
fun getMassage2(error: Error2) = when(error){
is Error2.DatabaseError -> "error is databaseError ${error.database.name}"
is Error2.FileError -> "error is fileError ${error.filename}"
is Error2.RedisError -> "error is redisError ${error.host}"
}
class Account {
var balance: long = 0
private set
}
toString을 쓴 것 처럼 객체 안의 내용을 확인 가능 => 객체 조회시 이름@주소가 아니라, 주 생성자의 값들이 출력됨
data class User(val name: String, val age: Int)
object NumberUtil {
fun sum(a:Int, b:Int) = a+b
fun multiply(a:Int, b:Int) = a*b
}
fun main() {
println(NumberUtil.multiply(10 ,2))
}
참고 : companion Object
data class Child (val name:String, val age:Int){
companion object {
const val MAX_CHILDREN = 4
fun ofDefaultAge(subName:String):Child{
return Child(subName, 0)
}
}
}
