Java ◦ is too verbose ◦ burden of previous versions ◦ Null Pointer Exception issues ◦ util “hell” • Android ◦ we need inheritance for almost everything ◦ api ceremony ◦ nullability ◦ lack of Java 8 features (lambdas, stream api, method reference...)
This can be null or not-null Nullability var name: String = null // compile error text?.length // compiles ⇔ if ( text != null) { text.length // smart casted to not-nullable type } name.length // this is ok since type is not nullable
if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (age != user.age) return false; if (!name.equals(user.name)) return false; return email.equals(user.email); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + email.hashCode(); result = 31 * result + age; return result; } } class User { private final String name; private final String email; private final int age; User(String name, String email, int age) { this.name = name; this.email = email; this.age = age; } public String getName() { return name; } public String getEmail() { return email; } public int getAge() { return age; } @Override public String toString() { return "User{ name='" + name + '\'' + ", email='" + email + '\'' + ", age=" + age + '}'; }
if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (age != user.age) return false; if (!name.equals(user.name)) return false; return email.equals(user.email); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + email.hashCode(); result = 31 * result + age; return result; } } class User { private final String name; private final String email; private final int age; User(String name, String email, int age) { this.name = name; this.email = email; this.age = age; } public String getName() { return name; } public String getEmail() { return email; } public int getAge() { return age; } @Override public String toString() { return "User{ name='" + name + '\'' + ", email='" + email + '\'' + ", age=" + age + '}'; }
if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (age != user.age) return false; if (!name.equals(user.name)) return false; return email.equals(user.email); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + email.hashCode(); result = 31 * result + age; return result; } class User ( val name: String, val email: String, val age: Int ) @Override public String toString() { return "User{ name='" + name + '\'' + ", email='" + email + '\'' + ", age=" + age + '}'; }
String, val email: String, val age: Int ) val user = User("John Smith", "[email protected]", 24) val newUser = user.copy(name = "Sam") //newUser == User("Sam", "[email protected]", 24) val (name, email, age) = newUser
val email: String, val age: Int) • Kotlin classes are final by default • we need to annotate class as open, if we want to inherit them • data classes can’t be inherited class limitations:
val email: String, val age: Int) • Kotlin classes are final by default • we need to annotate class as open, if we want to inherit them • data classes can’t be inherited class limitations:
is random message!".swapSpacesForUnderscore() // returns "This_is_random_message!" Compiles to: public static final String swapSpacesForUnderscore(@NotNull String $receiver) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver"); return $receiver.replace(," ", "_"); }
x,y -> x+y } add(1,2) val validator: (String) -> Boolean ={ value -> value.contains("@") } validator("[email protected]") • function expressions are blocks of code which we can instantiate(represent as type)
x,y -> x+y } add(1,2) • function expressions are blocks of code which we can instantiate(represent as type) val validator: (String) -> Boolean ={ it.contains("@") } validator("[email protected]")
x,y -> x+y } add(1,2) val validator: (String) -> Boolean ={ it.contains("@") } validator("[email protected]") mailTextview.validateWith{ validator("[email protected]") } • function expressions are blocks of code which we can instantiate(represent as type)
without overriding existing methods • Function expressions - undeclared function body used as an expression • Higher order function - function that accepts function or returns function
Any>) { val key = pair.first val value = pair.second when(value) { is String -> putString(key, value) is Int -> putInt(key, value) is Boolean -> putBoolean(key, value) is Float -> putFloat(key, value) is Long -> putLong(key, value) else -> error(“Only primitive types are supported”) } }
to user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) { val editor = edit() editor.func() editor.commit() }
to user.email) } } Extension / Higher order function expression combo inline fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) { val editor = edit() editor.func() editor.commit() }
values and named arguments) • classes and data classes • extension functions and properties • function expression • higher order functions • ultra mega giga combo of three above concepts • use inline modifier
Anko • Kotlin koans • Awesome Kotlin – collection of materials • Slack kanal • Design patterns in Kotlin • Keddit - demo app • Kotlin For Android (at DevFest İzmir 2016) • Kotlin – Ready for Production – Hadi Hariri • Android development with Kotlin – Jake Wharton
Group Serbia Nesh_Wolf [email protected] Kotlin User Group Serbia https://www.meetup.com/Serbia-Kotlin-User-Group https://www.facebook.com/kotlinserbia/ https://twitter.com/kotlin_serbia