Kotlin 文件以 .kt 爲後綴。html
kotlin源文件不須要相匹配的目錄和包,源文件能夠放在任何文件目錄。java
若是沒有指定包,默認爲 default 包。git
package basic.kotlin.manager.beijing /** * 定義類 */ class 總經理(var 姓: String) { override fun toString(): String { return "${姓}經理" } }
package basic.kotlin.manager.beijing import basic.kotlin.manager.beijing.總經理 as 茶水大王 // 起一個別名 /** * 包必須聲明在非註釋的第一行 */ fun main(args: Array<String>) { val manager: 茶水大王 = 茶水大王("張") println(manager) }
有多個包會默認導入到每一個 Kotlin 文件中: kotlin.* kotlin.annotation.* kotlin.collections.* kotlin.comparisons.* kotlin.io.* kotlin.ranges.* kotlin.sequences.* kotlin.text.*
定義常量與變量github
可變變量定義:var 關鍵字web
var <標識符> : <類型> = <初始化值>spring
不可變變量定義:val 關鍵字,只能賦值一次的變量(相似Java中final修飾的變量)數組
val <標識符> : <類型> = <初始化值>
package basic.kotlin
/**
* 基本數據類型
* 變量名稱:變量類型=變量值
*/
val aBoolean: Boolean = true
val anotherBoolean: Boolean = false
val anInt: Int = 8
val anotherInt: Int = 0xFF
val moreInt: Int = 0b00000011
val maxInt: Int = Int.MAX_VALUE
val minInt: Int = Int.MIN_VALUE
val aLong: Long = 12368172397127391
val another: Long = 123
val maxLong: Long = Long.MAX_VALUE
val minLong: Long = Long.MIN_VALUE
val aFloat: Float = 2.0F
val anotherFloat: Float = 1E3f
val maxFloat: Float = Float.MAX_VALUE
val minFloat: Float = -Float.MAX_VALUE
val aDouble: Double = 3.0
val anotherDouble: Double = 3.1415926
val maxDouble: Double= Double.MAX_VALUE
val minDouble: Double= -Double.MAX_VALUE
val aShort: Short = 127
val maxShort: Short = Short.MAX_VALUE
val minShort: Short = Short.MIN_VALUE
val aByte:Byte=127
val maxByte: Byte = Byte.MAX_VALUE
val minByte: Byte = Byte.MIN_VALUE
val aChar: Char = '0'
val bChar: Char = '中'
val cChar: Char = '\u56fd'
val dChar: Char = '\u000f'
fun main(args: Array<String>) {
println(anotherInt)
println(moreInt)
println(maxInt)
println(Math.pow(2.0, 31.0) - 1)
println(minInt)
println( - Math.pow(2.0, 31.0))
println(maxLong)
println(Math.pow(2.0, 63.0) - 1)
println(minLong)
println(- Math.pow(2.0, 63.0))
println(aFloat)
println(anotherFloat)
println(maxFloat)
println(minFloat)
println(maxDouble)
println(minDouble)
println(maxShort)
println(minShort)
println(aByte)
println(maxByte)
println(minByte)
println(aChar)
println(bChar)
println("Unicode:"+cChar) // 須要轉義才能打印
println("Unicode:"+dChar) // 須要轉義才能打印
}
package basic.kotlin
/**
* Range 區間
*/
val range: IntRange = 0..1024 // [0, 1024] 閉區間
val range_exclusive: IntRange = 0 until 1024 // [0, 1024) = [0, 1023] 開區間
val emptyRange: IntRange = 0..-1
fun main(args: Array<String>) {
println(emptyRange.isEmpty()) // 是否爲空
println(range.contains(50)) // 是否包含
println(50 in range) // 是否在這個區間
for(i in range_exclusive){ // 循環遍歷
print("$i, ")
}
}
package basic.kotlin
/**
* 隱式轉換 與 字符串類型
*/
val aInt:Int= 6
val bLong:Long= aInt.toLong() // int整形轉換爲long類型須要顯示轉換,在kotlin中不支持隱式轉換
val string: String = "HelloWorld"
val fromChars: String = String(charArrayOf('H','e','l','l','o','W','o','r','l','d'))
fun main(args: Array<String>) {
println(bLong)
println(string == fromChars) // 雙等號 比較內容 至關於java中的equals
println(string === fromChars) // 三等號 比較引用 至關於java 中比較的引用的地址
println("接下來咱們要輸出:" + string)
val arg1: Int = 0
val arg2: Int = 1
println("" + arg1 + " + " + arg2 + " = " + (arg1 + arg2)) // java傳統方式進行字符串拼接
println("$arg1 + $arg2 = ${arg1 + arg2}") // 字符串模板進行字符拼接
//Hello "Trump"
val sayHello : String = "Hello \"Trump\"" // 雙引號轉義
println(sayHello)
//salary
val salary: Int = 1000
//$salary
println("$$salary")
println("\$salary")
// 三個雙引號的字符串原樣輸出,在這種字符串模板拼接時,\ 進行轉義時不起做用
val rawString: String = """
\t
\n
$salary
\$salary
$ salary
"""
println(rawString)
println(rawString.length)
}
package com.basic.kotlin
/**
* 對象繼承關係
*/
// 類的定義方式一:
class 妹子(性格: String, 長相: String, 聲音: String): person(性格, 長相, 聲音)
// 類的定義方式二:
class 帥哥(性格: String, 長相: String, 聲音: String): person(性格, 長相, 聲音){
fun say(){
println("我最帥")
}
}
class 大叔(性格: String, 長相: String, 聲音: String): person(性格, 長相, 聲音){
init{
println("我有房、有車、有存款,我在父類的init方法後運行,在本身的實例每次建立被new時先運行")
}
}
open class person(var 性格: String, var 長相: String, var 聲音: String){
init {
println("new 了一個${this.javaClass.simpleName}, ta性格:$性格, 長相:$長相, 聲音:$聲音")
}
}
fun main(args: Array<String>) {
val girl: 妹子 = 妹子("溫柔", "甜美", "動人")
println(girl is person)
val boy: 帥哥 = 帥哥("彪悍", "帥氣", "渾厚")
boy.say()
val uncle: 大叔 = 大叔("穩重", "成熟", "洪亮")
}
package basic.kotlin
/**
* 空值安全
* 安全的kotlin寫法
*/
fun getName(): String?{ // ? 表示返回值的String類型容許爲null
return null
}
fun main(args: Array<String>) {
val str: String? = null //值容許爲空
println(str?.length) //值爲空直接返回null
val value: String? = "HelloWorld"
println(value!!.length) // 已經明確知道不爲空,!! 告訴編譯器,我知道是不爲空了,你編譯吧
val name: String = getName() ?: return // ? 表示容許爲null 爲空直接返回,下邊的打印語句不會執行了
println(name.length)
}
/** * 父類 */ public class Parent { }
/** * 子類繼承父類 */ public class Child extends Parent { public String getName(){ return "Child"; } }
package basic.kotlin
/**
* 智能識別類型轉換
* 安全的kotlin寫法
*/
fun main(args: Array<String>) {
val p: Parent = Parent()
val c: Parent = Child()
if (c is Child) // 類型相等,就能夠執行方法體的內容
println(c.name)
val child: Child? = p as? Child // 轉換失敗不讓其拋出異常,返回個null ,不帶?就會和java原生語法同樣拋出異常
println(child)
val string: String? = "Hello"
if(string != null)
println(string.length) // 智能甄別 ,前邊判斷了,後邊不用判斷了
}
package basic.kotlin
import basic.kotlin.manager.beijing.總經理 as m1
/**
* 數組
*/
val arrayOfInt: IntArray = intArrayOf(1,3,5,7)
val arrayOfChar: CharArray = charArrayOf('H', 'e','l','l','o','W','o','r','l','d')
val arrayOfString: Array<String> = arrayOf("我", "是", "碼農")
val arrayOf經理: Array<m1> = arrayOf(m1("張"),m1("李"))
fun main(args: Array<String>) {
println(arrayOfInt.size)
for(int in arrayOfInt){
print("$int \t")
}
println()
println(arrayOfString.joinToString(""))
println(arrayOf經理[1])
arrayOf經理[1] = m1("王")
println(arrayOf經理[1]) // 取出第二個元素
println(arrayOfChar.joinToString()) // 字符串鏈接 默認逗號
println(arrayOfChar.joinToString("")) // 空字符串鏈接 ,就是一個完整的字符串
println(arrayOfInt.slice(1..2)) // 字符串區間截取子串
println(arrayOfInt.slice(0..1)) // 字符串區間截取子串
}
而後重啓idea===>從新編譯(構建項目)
tomcat
而後可以直接看java文件的字節碼安全
安裝完了以後一樣須要從新編譯,而後能夠直接查看java文件的asm 字節碼
springboot
在使用 intellij idea 編寫 kotlin 的時候,咱們能夠查看當前 kotlin 文件的字節碼。
Tools → Kotlin → Show Kotlin Bytecode
固然字節碼是很難看懂的。不要緊,咱們能夠把字節碼再反編譯成 java 代碼。
Windows下安裝和配置Kotlin
參考文檔:https://www.kotlincn.net/docs/tutorials/command-line.html
在JDK安裝完成後,就能夠安裝Kotlin了。Kotlin是跨平臺的,目前支持3種IDE:IntelliJ IDEA、Android Studio和Eclipse。不過在這一節,咱們先不考慮IDE的事情。
與Java同樣,安裝Kotlin後,首先看看是否能夠經過命令行方式運行Kotlin程序,這是入門Kotlin要進行的第一步。本節只考慮如何在Windows下安裝和配置Kotlin環境,首先進入下面列出的Kotlin官網。
將頁面滾動到下半部分,會看到如圖所示的4個下載區域。最右側的Compiler是Kotlin編譯器的下載頁面。
將壓縮包解壓放在本身喜歡的位置,而後仿照「配置JDK環境變量」的方式配置Kotlin的環境變量。
若是在命令行下輸入kotlinc顯示相似以下界面,說明配置成功。
編寫一個hello.kt,以下
fun main(args: Array<String>) { println("Hello, World!") }
使用kotlinc hello.kt編譯上面的文件,這時會在同一目錄下生成一個HelloKt.class,嘗試用java命令來運行HelloKt,結果會是NoClassDefFoundError!
那麼,應該如何運行這段代碼呢?根據官網的介紹大概是如下兩種方式。
方式一:使用Kotlin運行這段代碼
D:\IdeaProjects\Helloworld-kotlin\src\basic\kotlin>kotlinc hello.kt
D:\IdeaProjects\Helloworld-kotlin\src\basic\kotlin>kotlin HelloKt
Hello, World!
方式二:使用本地JVM運行這個JAR包
官方的命令爲:kotlinc hello.kt -include-runtime -d hello.jar
應該很好理解,運行上述命令以後將獲得一個hello.jar,運行這個JAR包:java -jar -hello.jar
D:\labs>java -jar hello.jar Hello, World!
證實Kotlin是徹底兼容JVM的
package basic.kotlin.test
/**
* var 與 val 定義變量:
* 一、var內容可變,能夠從新賦值
* 二、val內容不可變,不能夠從新賦值
* 三、類型推導
* val修飾的變量至關於java中被final修飾的類型變量--------運行時常量
* 當被const修飾時,編譯器會在編譯期間編譯爲具體的值,不然就是仍是對象的引用 ----------編譯期常量
*
**/
const val FINAL_HELLO_WORLD: String = "HelloWorld" // 不能夠從新賦值
var helloWorld: String = FINAL_HELLO_WORLD // 能夠從新賦值
val FINAL_HELLO_CHINA = "HelloChina" // 類型推導,由編譯器判斷。
// 默認返回值 Unit 至關於java中的void,就是什麼都不返回,也可省略
fun main(args: Array<String>) { // (Array<String>) -> Unit
// FINAL_HELLO_WORLD="qqqq"
helloWorld="123456" // 對var 修飾的常量進行從新賦值
println(helloWorld)
println(FINAL_HELLO_CHINA)
println("hello ${args[0]}")
var arrayOfstr: Array<String> = arrayOf("1","3")
checkArgs(arrayOfstr)
val arg1 = arrayOfstr[0].toInt()
val arg2 = arrayOfstr[1].toInt()
println("$arg1 + $arg2 = ${sum(arg1, arg2)}")
println(int2Long(3))
println(sum(1,3))
println(sum.invoke(1,3)) // invoke是 運算符重載
arrayOfstr.forEach(::println) // reference 寫法
// 不加ForEach@ 是退出forEach所在的函數,後面的代碼不會被執行
// 加ForEach@ 是退出整個for循環,後面的代碼依然會被執行
arrayOfstr.forEach ForEach@{
if(it == "3") return@ForEach
println(it)
}
println("The End")
println(sum)
println(int2Long)
println(::printUsage is ()-> Unit)
}
fun checkArgs(args: Array<String>) {
if (args.size != 2) {
printUsage()
System.exit(-1)
}
}
// 函數定義 --- 無返回值
fun printUsage() {
println("請傳入兩個整型參數,例如 1 2") // (Any?) -> Unit
} // ()->Unit
// lambda 表達式 (Int, Int) -> Int
val sum = { arg1: Int, arg2: Int ->
println("$arg1 + $arg2 = ${arg1 + arg2}")
arg1 + arg2
}
// ()-> Unit
val printlnHello = {
println("Hello")
}
// 匿名函數定義 有返回值
val int2Long = fun(x: Int): Long {
return x.toLong()
}
}
IDEA按鍵失效:經常使用快捷鍵:Ctrl+C Ctrl+V 選中刪除都不起效,緣由是IDEA勾選了Vim模式,
Tools,Vim Emulator,前面會有一個√,可,如圖:
把那個√取消便可解決問題。
package basic.kotlin.function
/**
* 測試 屬性和方法 屬性的getter 和setter是默認實現,也能夠手動重寫
*
* 默認訪問修飾符 public
* 私有的:protected、private
*
* lateinit 是屬性延遲初始化修飾符
*/
class Score
class Stu{
var age = 0 // getter 和 setter 只能放在當前屬性的正下方
get() {
println("測試getter方法")
return field
}
set(value) {
println("測試setter方法")
field=value
}
lateinit var name: String // 字符串引用類型懶加載賦值 在使用是必須初始化
lateinit var score: Score // 自定義對象類型懶加載賦值 在使用是必須初始化
val e: Score by lazy { // val 修飾的懶加載賦值,經過 by lazy ,在使用是必須初始化
println("初始化 Score")
Score()
}
var cc: String? = null
}
fun main(args: Array<String>) {
val stu = Stu()
println(stu.age) // 等價於 stu.getAge()
stu.age=30
println(stu.age) // 使用以前須要初始化
stu.name="張三" // 使用以前須要初始化
println(stu.name) // lateinit property name has not been initialized
println(stu.e) // 在定義時初始化
stu.score = Score() // 初始化賦值
println(stu.score) // 打印的對象名,使用以前初始化
println(stu.cc?.length) // 空值的條件判斷
}
package basic.kotlin.function
/**
* 運算符:本質上就是一個函數
* + 實際上對應的是kotlin的默認plus 方法
* 咱們能夠本身定義plus的重載方法 寫本身的運算符實現
*
*/
//c1.plus(c2) 返回值 Complex
class Complex(var real: Double, var imaginary: Double){
// 重載方法:1 參數Complex, 返回值 Complex
operator fun plus(other: Complex): Complex{
return Complex(real + other.real, imaginary + other.imaginary)
}
// 重載方法:2 參數Complex,返回值 Complex
operator fun plus(other: Int): Complex{
return Complex(real + other, imaginary)
}
// 重載方法:3 參數Any,返回值 Int
operator fun plus(other: Any): Int {
return (real + imaginary).toInt()
}
// 重載方法:4
operator fun invoke(): Double{
return Math.hypot(real, imaginary) // q取模運算
}
override fun toString(): String {
return "結果:$real + ${imaginary}"
}
}
//中綴符號表達式,用於兩個對象間的運算
class Book{
infix fun on(any: Any): Boolean{
return false
}
}
class Desk
fun main(args: Array<String>) {
// + 實際上對應的是kotlin的默認plus 方法
println(1 + 2)
val c1 = Complex(3.0, 4.0)
val c2 = Complex(2.0, 5.0)
println(c1 + c2) // 結果:5.0 + 9.0 第一個重載方法 等價於 println(c1.plus(c2))
println(c1 + 5) // 結果:8.0 + 4.0第二個重載方法 等價於 println(c1.plus(5))
println(c1 + "haha") // 7 第三個重載方法 等價於 println(c1.plus("haha"))
println(c1()) // 5.0 第四個重載方法 等價於 println(c1.invoke())
//字符串包含
val arrayOfStr: Array<String> = arrayOf("my","name","is黑客")
if("name" in arrayOfStr){ // 等價於 arrayOfStr.contains("name")
println(arrayOfStr[arrayOfStr.indexOf("name") + 1])
}
if(Book() on Desk()){ // dsl
}
}
package basic.kotlin.function
/**
* 分支表達式 if 、when
*/
private const val USERNAME = "kotlin"
private const val PASSWORD = "123"
private const val ADMIN_USER = "admin"
private const val ADMIN_PASSWD = "admin"
private const val DEBUG = 1
private const val USER = 0
fun main(args: Array<String>) {
val x = 5
when(x){ // 只會執行其中的一個
is Int -> println("Hello $x") // 判斷 是不是int類型
in 1..100 -> println("$x is in 1..100") // 判斷是不是在區間中
!in 1..100 -> println("$x is not in 1..100") // 判斷是不是不在區間中
args[0].toInt() -> println("x == args[0]") // x 和當前表達式是否同樣
}
// 至關於if else
val wh = when{
args.isNotEmpty() && args[0] == "1"
-> 1
else -> 0
}
println(wh)
// if表達式 帶返回值
val mode = if(args.isNotEmpty() && args[0] == "1"){
DEBUG
}else{
USER
}
println("請輸入用戶名:")
val username = readLine()
println("請輸入密碼:")
val passwd = readLine()
if(mode == DEBUG && username == ADMIN_USER && passwd == ADMIN_PASSWD) {
println("管理員登陸成功")
}else if(username == USERNAME && passwd == PASSWORD){
println("登陸成功")
}else{
println("登陸失敗")
}
}
package basic.kotlin.function
/**
* 跳過continue 和 跳出break 循環
*/
class Student{
fun isNotClothedProperly(): Boolean{
return false
}
}
fun main(args: Array<String>) {
val students = ArrayList<Student>()
val you = Student()
for (student in students){
if(student == you) continue
if(student.isNotClothedProperly()){
break
}
}
}
package basic.kotlin.function
/**
* for 循環 和 while 循環 語句
*/
fun main(args: Array<String>) {
val arrayOfStr: Array<String> = arrayOf("my","name","is黑客")
var x = 5
while(x > 0){
println(x)
x--
}
do{
println(x)
x--
}while (x > 0)
for (arg in arrayOfStr){
println(arg)
}
for((index, value) in arrayOfStr.withIndex()){
println("$index -> $value")
}
for(indexedValue in arrayOfStr.withIndex()){
println("${indexedValue.index} -> ${indexedValue.value}")
}
val list = MyIntList()
list.add(1)
list.add(2)
list.add(3)
for(i in list){
println(i)
}
}
class MyIterator(val iterator: Iterator<Int>){
operator fun next(): Int{
return iterator.next()
}
operator fun hasNext(): Boolean{
return iterator.hasNext()
}
}
class MyIntList{
private val list = ArrayList<Int>()
fun add(int : Int){
list.add(int)
}
fun remove(int: Int){
list.remove(int)
}
operator fun iterator(): MyIterator{
return MyIterator(list.iterator())
}
}
package basic.kotlin.function
/**
* 異常捕獲
*/
fun main(args: Array<String>) {
val res = try {
val result = 1/0
}catch (e: Exception){
println("程序出現了未知異常,多是您的人品太差了。${e.message}")
0
}finally {
println("謝謝您使用咱們的加法計算器")
}
println(res)
}
具名參數:參數賦值到具體名稱,沒有順序
變長參數:在java裏是最後一個參數,在kotlin沒有這種限制
默認參數:調用時不傳入參數,能夠採用設置默認值
package basic.kotlin.function
/**
* 具名參數:參數賦值到具體名稱,沒有順序
* 變長參數:在java裏是最後一個參數,在kotlin沒有這種限制
* 默認參數:調用時不傳入參數,能夠採用設置默認值
*/
fun main(vararg args: String) {
// for (arg in args){
// println(arg)
// }
val list = arrayListOf(1,3,4,5)
val array = intArrayOf(1,3,4,5)
hello(3.0, *array)
}
fun hello(double: Double, vararg ints: Int, string: String = "Hello"){
println(double)
ints.forEach(::println)
println(string)
}
在導入工程後,經過gradle的工具建立生成war,war包的名稱和settings.gradle的 rootProject.name = 'servlet-web-applications' 一致
方式一:打成war包運行
手動放到tomcat容器,雙擊運行tomcat。