Kotlin与Java的几种单例模式
生活随笔
收集整理的這篇文章主要介紹了
Kotlin与Java的几种单例模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、餓漢式(線程安全,調用效率高,但是不能延時加載)
JAVA例子:
public class Test {private static Test test = new Test();private Test() {}public static Test getInstance() {return test;}// 忽略方法printTest(),僅用來輸出public void printTest() {System.out.println("maisomgan:java-test");} }Kotlin例子:
object Test1 {// 忽略方法printTest(),僅用來輸出fun printTest() {println("maisomgan:kotlin-test")} }在Kotlin代碼類型中進行調用:
Test.getInstance().printTest() Test1.printTest()輸出結果:
二、懶漢式(線程安全,調用效率不高,但是能延時加載)
Java例子:
public class Test {private static Test test;private Test() {}public static Test getInstance() {if (test == null) {test = new Test();}return test;}// 忽略方法printTest(),僅用來輸出public void printTest() {System.out.println("maisomgan:java-test");} }Kotlin例子:
class Test1 private constructor() {companion object {private var test1: Test1? = nullget() {if (field == null) {field = Test1()}return field}fun getInstance(): Test1 {return test1!!}}// 忽略方法printTest(),僅用來輸出fun printTest() {println("maisomgan:kotlin-test")} }在Kotlin代碼類型中進行調用:
Test.getInstance().printTest() Test1.getInstance().printTest()輸出結果:
三、線程安全的懶漢式
Java例子:
public class Test {private static Test test;private Test() {}public static synchronized Test getInstance() {if (test == null) {test = new Test();}return test;}// 忽略方法printTest(),僅用來輸出public void printTest() {System.out.println("maisomgan:java-test");} }Kotlin例子:
class Test1 private constructor() {companion object {private var test1: Test1? = nullget() {if (field == null) {field = Test1()}return field}@Synchronizedfun getInstance(): Test1 {// !!表示該屬性一定不能為Null,否則將拋出空指針異常錯誤導致crashreturn test1!!}}// 忽略方法printTest(),僅用來輸出fun printTest() {println("maisomgan:kotlin-test")} }在Kotlin代碼類型中進行調用:
Test.getInstance().printTest() Test1.getInstance().printTest()輸出結果:
四、雙重校驗鎖式雙重鎖判斷機制(由于JVM底層模型原因,偶爾會出問題,不建議使用)
Java例子:
public class Test {// volatile關鍵字保證了test成員變量的可見性,一定程度上保護了線程的安全// new 操作不是原子操作,在 JVM 層面會導致重排序// volatile在此主要是禁止重排序(synchronized只能保證有序性卻不能禁止重排序)private volatile static Test test;private Test() {}public static Test getInstance() {if (test == null) {synchronized (Test.class) {if (test == null) {test = new Test();}}}return test;}// 忽略方法printTest(),僅用來輸出public void printTest() {System.out.println("maisomgan:java-test");} }Kotlin例子:
class Test1 private constructor() {companion object {// lazy是Kotlin的延遲屬性val test1: Test1 by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {Test1()}}// 忽略方法printTest(),僅用來輸出fun printTest() {println("maisomgan:kotlin-test")} }在Kotlin代碼類型中進行調用:
Test.getInstance().printTest() Test1.test1.printTest()輸出結果:
五、靜態內部類式(線程安全,調用效率高,可以延時加載)
Java例子:
public class Test {private static class Singleton {private static Test test = new Test();}private Test() {}public static Test getInstance() {return Singleton.test;}// 忽略方法printTest(),僅用來輸出public void printTest() {System.out.println("maisomgan:java-test");} }Kotlin例子:
class Test1 private constructor() {companion object {val test1 = Singleton.singleton}private object Singleton {val singleton = Test1()}// 忽略方法printTest(),僅用來輸出fun printTest() {println("maisomgan:kotlin-test")} }在Kotlin代碼類型中進行調用:
Test.getInstance().printTest() Test1.test1.printTest()輸出結果:
六、枚舉類實現單例(線程安全,調用效率高,不能延時加載,可以天然的防止反射和反序列化調用)
Java例子:
public enum Test {// 枚舉元素本身就是單例INSTANCE;// 忽略方法printTest(),僅用來輸出public void printTest() {System.out.println("maisomgan:java-test");} }Kotlin例子:
enum class Test1 {// 枚舉元素本身就是單例INSTANCE;// 忽略方法printTest(),僅用來輸出fun printTest() {println("maisomgan:kotlin-test")} }在Kotlin代碼類型中進行調用:
Test.INSTANCE.printTest() Test1.INSTANCE.printTest()輸出結果:
如何選用:
-
單例對象 占用資源少,不需要延時加載,枚舉 好于 餓漢
-
單例對象 占用資源多,需要延時加載,靜態內部類 好于 懶漢式
總結
以上是生活随笔為你收集整理的Kotlin与Java的几种单例模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 使用 ActivityR
- 下一篇: java美元兑换,(Java实现) 美元