Learn & build Kotlin + spring based backend
Kotlin Repository:
-
basic: Kotlin basic
-
springBoot: spring boot + gradle + RESTful api
-
springsql: spring boot + gradle + PostgreSQL + RESTful api
-
springrestful: spring (boot + security) + gradle + OAuth2 + JWT + PostgreSQL + RESTful api
-
fullstack: in progress ...
5.1 backend: in progress ...
5.2 frontend: in progress ...
Classes, objects, interfaces, constructors, functions, properties and their setters can have visibility modifiers. (Getters always have the same visibility as the property.)
There are four visibility modifiers in Kotlin:
- private:
only be visible inside the file containing the declaration
- protected:
is not available for top-level declarations
- internal:
is visible everywhere in the same module
- public.
The default visibility, used if there is no explicit modifier, is public.
Packages:
// file name: example.kt
package foo
private fun foo() {} // visible inside example.kt
public var bar: Int = 5 // property is visible everywhere
private set // setter is visible only in example.kt
internal val baz = 6 // visible inside the same module
Classes and Interfaces: For members declared inside a class:
private
means visible inside this class only (including all its members);protected
— same as private + visible in subclasses too;internal
— any client inside this module who sees the declaring class sees its internal members;public
— any client who sees the declaring class sees its public members.
open class Outer {
private val a = 1
protected open val b = 2
internal val c = 3
val d = 4 // public by default
protected class Nested {
public val e: Int = 5
}
}
class Subclass : Outer() {
// a is not visible
// b, c and d are visible
// Nested and e are visible
override val b = 5 // 'b' is protected
}
class Unrelated(o: Outer) {
// o.a, o.b are not visible
// o.c and o.d are visible (same module)
// Outer.Nested is not visible, and Nested::e is not visible either
}
- Collections: List, Set, Map
- Null Safety
- This Expression
- Annotations
- Calling Java code from Kotlin
- Calling Kotlin from Java
- Type Aliases
- Kotlin programmer dictionary: Function vs Method vs Procedure
- Kotlin programmer dictionary: Statement vs Expression
- Kotlin Programmer Dictionary: Function Type vs Function literal vs Lambda expression vs Anonymous function
- its name should be the same as the name of the class
ProcessDeclarations.kt
- The name of the file should describe what the code in the file does
- Names of packages are always lower case and do not use underscores
org.example.myproject
- Names of classes and objects start with an upper case letter and use camel humps:
open class DeclarationProcessor { ... }
object EmptyDeclarationProcessor : DeclarationProcessor() { ... }
- Function names
- Names of
functions
,properties
and localvariables
start with a lower case letter and use camel humps and no underscores fun processDeclarations() { ... }
- Names of
- Property names
- Names of constants (properties marked with const, or top-level or object val properties with no custom get function that hold deeply immutable data) should use uppercase underscore-separated names
const val MAX_COUNT = 8
val USER_NAME_FIELD = "UserName"
- Names of properties holding references to singleton objects can use the same naming style as object declarations:
val PersonComparator: Comparator<Person> = ...
- Names of constants (properties marked with const, or top-level or object val properties with no custom get function that hold deeply immutable data) should use uppercase underscore-separated names
If a declaration has multiple modifiers, always put them in the following order:
public / protected / private / internal
expect / actual
final / open / abstract / sealed / const
external
override
lateinit
tailrec
vararg
suspend
inner
enum / annotation
companion
inline
infix
operator
data
Place all annotations before modifiers:
@Named("Foo")
private val foo: Foo
- Prefer using immutable data to mutable. Always declare local variables and properties as
val
rather thanvar
if they are not modified after initialization. - Always use immutable collection interfaces (Collection, List, Set, Map) to declare collections which are not mutated. When using factory functions to create collection instances, always use functions that return immutable collection types when possible:
// Bad: use of mutable collection type for value which will not be mutated
fun validateValue(actualValue: String, allowedValues: HashSet<String>) { ... }
// Good: immutable collection type used instead
fun validateValue(actualValue: String, allowedValues: Set<String>) { ... }
// Bad: arrayListOf() returns ArrayList<T>, which is a mutable collection type
val allowedValues = arrayListOf("a", "b", "c")
// Good: listOf() returns List<T>
val allowedValues = listOf("a", "b", "c")
Prefer declaring functions with default parameter values to declaring overloaded functions.
// Bad
fun foo() = foo("a")
fun foo(a: String) { ... }
// Good
fun foo(a: String = "a") { ... }
If you have a functional type or a type with type parameters which is used multiple times in a codebase, prefer defining a type alias for it:
typealias MouseClickHandler = (Any, MouseEvent) -> Unit
typealias PersonIndex = Map<String, Person>
Gradle is a build tool with a focus on build automation and support for multi-language development. If you are building, testing, publishing, and deploying software on any platform, Gradle offers a flexible model that can support the entire development lifecycle from compiling and packaging code to publishing web sites. Gradle has been designed to support build automation across multiple languages and platforms including Java, Scala, Android, C/C++, and Groovy, and is closely integrated with development tools and continuous integration servers including Eclipse, IntelliJ, and Jenkins.
The Gradle Kotlin DSL provides support for writing Gradle build scripts using JetBrains' Kotlin language. It aims to provide Gradle users with a rich, flexible and statically-typed approach to developing build logic in conjunction with the best IDE and tooling experience possible.