Kotlin開發springboot項目(二)

Kotlin開發springboot項目(二)

中文學習網站:

https://www.kotlincn.net/

研究一下kotlin的demo:

https://github.com/JetBrains/kotlin-examples

 

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) // 須要轉義才能打印
}

 Range區間

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, ")
}
}

 

 kotlin不支持隱式轉換

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)
}

kotlin中Any是全部類的父類

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 查看字節碼 bytecode插件 (jclasslib Bytecode Viewer、ASM Bytecode Viewer )

jclasslib Bytecode Viewer

在這裏插入圖片描述
而後重啓idea===>從新編譯(構建項目)
在這裏插入圖片描述
在這裏插入圖片描述tomcat

而後可以直接看java文件的字節碼安全

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

ASM Bytecode Viewer

在這裏插入圖片描述
安裝完了以後一樣須要從新編譯,而後能夠直接查看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官網。

https://kotlinlang.org

將頁面滾動到下半部分,會看到如圖所示的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,前面會有一個√,可,如圖:

把那個√取消便可解決問題。

kotlin屬性和函數

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) // 空值的條件判斷
}

 kotlin的運算符

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
}

}

分支表達式 if、when

 

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)
}

 

先以 Http Servlet 建立 Web 應用 爲例

在導入工程後,經過gradle的工具建立生成war,war包的名稱和settings.gradle的 rootProject.name = 'servlet-web-applications' 一致

方式一:打成war包運行

 手動放到tomcat容器,雙擊運行tomcat。

 

方式二:

IDEA 中添加tomcat容器的方式運行工程

 

相關文章
相關標籤/搜索