Java里的static在Kotlin里如何實(shí)現(xiàn)
static修飾符是java里面非常常用的一個(gè)東西,用法也非常多。然而,在kotlin里竟然沒有這個(gè)東西!那該如何替代呢?本文就總結(jié)了下java里面static的幾種常見用法在kotlin里的替代方式。
static在java里面的用法總結(jié)
static在java里面的用法有很多,最常用的有下面幾種:
- 靜態(tài)變量及方法
- 靜態(tài)初始化
- 靜態(tài)內(nèi)部類
下面我們就看看這幾種場(chǎng)景在kotlin是如何實(shí)現(xiàn)的。
場(chǎng)景一:靜態(tài)變量及方法
靜態(tài)變量及方法可能是我們平時(shí)用到static最多的地方,我們先看看java里面是如何做的。
java靜態(tài)變量及方法介紹:
首先,是靜態(tài)變量和方法的定義:
public class StaticTest { public static int STATIC_VAR = 0; public static void staticMethod(String str){ System.out.println(str); } }
然后是靜態(tài)變量和方法的使用:
StaticTest.STATIC_VAR = 10; StaticTest.staticMethod("hello");
java的實(shí)現(xiàn)方式大家都非常熟悉了,下面著重說說kotlin是如何實(shí)現(xiàn)的。
kotlin替代靜態(tài)變量及方法的方案
kotlin通過引入“伴生對(duì)象”的概念來替代java里的靜態(tài)變量及方法。
“伴生對(duì)象”這個(gè)名詞聽上去很古怪,其實(shí)非常簡(jiǎn)單:在類的內(nèi)容使用companion來標(biāo)記一個(gè)對(duì)象。所有需要“靜態(tài)化”的變量和方法都放在這個(gè)對(duì)象里。
下面是定義伴生對(duì)象的代碼:
class StaticTest { companion object{//伴生對(duì)象是可以指定名字的,不過一般都省略掉。 var STATIC_VAR = 0 fun staticMethod(str: String?) { println(str) } } }
接下來看看如何使用伴生對(duì)象,伴生對(duì)象只能通過類名來訪問,使用方法和java差不多:
StaticTest.STATIC_VAR = 100 StaticTest.staticMethod("hello")
kotlin的伴生對(duì)象解決了什么問題?
大家可能會(huì)好奇,為什么kotlin要用這么一個(gè)奇怪的方式來解決這個(gè)問題呢?
我的理解是有兩個(gè)原因:
第一,使用伴生對(duì)象體現(xiàn)了kotlin一貫的設(shè)計(jì)理念:一切都是對(duì)象!伴生對(duì)象也是對(duì)象!而java的static,顯然和對(duì)象沒有關(guān)系。
第二,伴生對(duì)象解決了java靜態(tài)變量及方法的一個(gè)常見的反模式:靜態(tài)方法及變量可以通過對(duì)象的引用來訪問。
還是拿上面的例子,java的靜態(tài)變量及方法可以通過類引用和對(duì)象引用兩種方法訪問:
//通過類引用訪問 StaticTest.STATIC_VAR = 10; StaticTest.staticMethod("hello"); //通過對(duì)象引用訪問 StaticTest obj = new StaticTest(); obj.STATIC_VAR = 10; obj.staticMethod("hello");
而通過對(duì)象引用訪問靜態(tài)變量及方法,顯然是不合適的。但是在java里卻沒有辦法從語(yǔ)法層面避免這個(gè)問題。
而kotlin的伴生對(duì)象只能通過類引用訪問,從語(yǔ)法的層面解決了這個(gè)問題:
//使用類引用訪問 StaticTest.STATIC_VAR = 100 StaticTest.staticMethod("hello") //不能使用對(duì)象引用訪問 val obj = StaticTest() obj.STATIC_VAR = 100 //編譯錯(cuò)誤 obj.staticMethod("hello") //編譯錯(cuò)誤
總之,kotlin里每個(gè)新的語(yǔ)言特性,都是為了填補(bǔ)java的某一個(gè)坑。
場(chǎng)景二:靜態(tài)初始化
java里的靜態(tài)初始化可以在類加載的時(shí)候初始化一些靜態(tài)變量,比如:
public class StaticTest { public static int STATIC_VAR = 0; static { STATIC_VAR = 100; System.out.println("in static init"); } public static void main(String[] args) { System.out.println(StaticTest.STATIC_VAR); } }
上面的代碼執(zhí)行結(jié)果如下:
in static init
100
在kotlin里,因?yàn)閖ava的靜態(tài)變量及方法都是放在伴生對(duì)象里實(shí)現(xiàn)的,而伴生對(duì)象也是一個(gè)普通對(duì)象,所以可以通過伴生對(duì)象的init方法來實(shí)現(xiàn)變量的初始化,代碼如下:
class StaticTest { companion object{//伴生對(duì)象是可以指定名字的,不過一般都省略掉。 var STATIC_VAR = 0 init { STATIC_VAR = 100 println("in companion object init") } } }
執(zhí)行代碼:
println(StaticTest.STATIC_VAR)
結(jié)果如下:
in companion object init
100
可以看到,kotlin的實(shí)現(xiàn)方式要比java的更加一致,既然大家都是對(duì)象,所以都是通過init來初始化的。而java里,非靜態(tài)變量是通過構(gòu)造函數(shù)來初始化的,而靜態(tài)變量是通過static代碼塊來初始化的,兩者很不一致。
場(chǎng)景三:靜態(tài)內(nèi)部類
java的內(nèi)部類有兩種,普通內(nèi)部類和靜態(tài)內(nèi)部類。二者的區(qū)別是前者可以訪問外部類的變量,而后者不可以。同時(shí)普通內(nèi)部類會(huì)持有外部類的一個(gè)引用,靜態(tài)內(nèi)部類則沒有。
public class StaticTest { private int out = 0; class InnerClass{ public void InnerClassMethod(){ out = 100; //可以訪問外部類的變量 } } static class StaticInnerClass{ public void StaticInnerClassMethod(){ out = 100; //編譯錯(cuò)誤,不可以訪問外部類的變量 } } }
而kotlin的內(nèi)部類也有兩種:內(nèi)部類和嵌套類。從語(yǔ)法上說,二值的差別就是前者多一個(gè)inner修飾符。
下面是和java的比較:
- kotlin的內(nèi)部類(使用inner修飾符)相當(dāng)于java的普通內(nèi)部類,可以訪問外部變量,同時(shí)持有外部對(duì)象的引用。
- kotlin的嵌套類(沒有inner修飾符)相當(dāng)于java的靜態(tài)內(nèi)部類,不可以訪問外部變量
kotlin嵌套類的例子:
class StaticTest { var out = 0 inner class InnerClass{ fun InnerClassMethod(){ out = 100 //內(nèi)部類可以訪問外部變量 } } }
kotlin內(nèi)部類的例子:
class StaticTest { var out = 0 class InnerClass{ fun InnerClassMethod(){ out = 100 //編譯錯(cuò)誤,嵌套類不可以訪問外部變量 } } }
通過對(duì)比,大家應(yīng)該很容易的搞清楚kotlin里內(nèi)部類和嵌套類的區(qū)別了。
總結(jié):
本文的知識(shí)點(diǎn)總結(jié)如下:
- java的靜態(tài)變量和方法,在kotlin中使用伴生對(duì)象替代
- java的靜態(tài)初始化,在kotlin中使用伴生對(duì)象的init替代
- java的靜態(tài)內(nèi)部類,在kotlin中使用嵌套類來替代
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:SpringBoot靜態(tài)視頻實(shí)時(shí)播放的實(shí)現(xiàn)代碼
欄 目:Java
下一篇:Spring AOP定義Before增加實(shí)戰(zhàn)案例詳解
本文標(biāo)題:Java里的static在Kotlin里如何實(shí)現(xiàn)
本文地址:http://mengdiqiu.com.cn/a1/Java/8750.html
您可能感興趣的文章
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)模擬時(shí)鐘
- 01-10利用Java實(shí)現(xiàn)復(fù)制Excel工作表功能
- 01-10JavaWeb實(shí)現(xiàn)郵件發(fā)送功能
- 01-10java基于poi導(dǎo)出excel透視表代碼實(shí)例
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)數(shù)字時(shí)鐘
- 01-10基于Java驗(yàn)證jwt token代碼實(shí)例
- 01-10java實(shí)現(xiàn)液晶數(shù)字字體顯示當(dāng)前時(shí)間
- 01-10淺談Java中真的只有值傳遞么
- 01-10Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間
- 01-10如何解決線程太多導(dǎo)致java socket連接池出現(xiàn)的問題


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)模擬時(shí)鐘
- 01-10Springboot中@Value的使用詳解
- 01-10JavaWeb實(shí)現(xiàn)郵件發(fā)送功能
- 01-10利用Java實(shí)現(xiàn)復(fù)制Excel工作表功能
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)數(shù)字時(shí)鐘
- 01-10java基于poi導(dǎo)出excel透視表代碼實(shí)例
- 01-10java實(shí)現(xiàn)液晶數(shù)字字體顯示當(dāng)前時(shí)間
- 01-10基于Java驗(yàn)證jwt token代碼實(shí)例
- 01-10Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間
- 01-10淺談Java中真的只有值傳遞么
隨機(jī)閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 04-02jquery與jsp,用jquery
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文