当前位置: 代码迷 >> 综合 >> Kotlin-7-静态工具类+单例对象+访问修饰符
  详细解决方案

Kotlin-7-静态工具类+单例对象+访问修饰符

热度:24   发布时间:2023-10-09 05:50:49.0

目录

1、Kotlin中的访问修饰符

2、静态方法

3、object关键字

3.1、对象表达式

3.2、对象声明

4、companion object(伴生对象)

5、静态工具类的实现:

6、单例的实现


1、Kotlin中的访问修饰符

修饰符 含义 与Java比较
public Kotlin中的默认修饰符,全局可见 与Java中public效果相同
protected 受保护的修饰符,仅类和子类可见 Java中还有包内可见
private 私有修饰符,类内修饰只有本类可见,类外修饰仅文件可见 Java中仅类内可见
internal 模块内可见

 

 

 

 

 

 

2、静态方法

 在Java中我们经常写这样的工具类,来进行开发。

public class StringUtil {public static boolean isEmpty(String str){return "".equals(str);}
}

那么Kotlin中的静态方法是怎么实现的呢?

首先我们来讲几个关键字。

3、object关键字

object 关键字可以表达两种含义:一种是对象表达式,另一种是 对象声明

3.1、对象表达式

object可以继承一个类,或者实现一个接口。(下面代码View.OnClickListener {} 属于将接口实例化成一个匿名内部类,然后用object来继承。)

        val text: TextView = findViewById(R.id.text)//基础表达text.setOnClickListener(View.OnClickListener {})//object 表达匿名内部类对象 (OnClickListener就是一个匿名内部类)val clicListener = object : View.OnClickListener {override fun onClick(v: View?) {}}//lambda简化OnClickListener匿名内部类val clicListener1 = View.OnClickListener {}text.setOnClickListener(clicListener1)

上面代码其实就是我们经常要给 view 设置的点击事件,OnClickListener 事件是一个匿名内部类的对象,用object来继承。

3.2、对象声明

object 修饰的类为静态类,里面的方法和变量都为静态的。

   3.2.1 直接声明类

object DemoManager {private val TAG = "DemoManager"fun test() {Log.e(TAG,"此时 object 表示 声明静态内部类")}}

   3.2.2 声明静态内部类

类内部的对象声明,没有被inner 修饰的内部类都是静态的

class DemoManager{object MyObject {fun test() {Log.e(TAG,"此时 object 表示 直接声明类")}}
}

4、companion object(伴生对象)

companion object 修饰为伴生对象,伴生对象在类中只能存在一个,且只能写在类里边。

它可以用来实现Java那种静态工具类和单例。

class StringUtils{companion object{fun isEmpty4(str: String): Boolean {return "" == str}@JvmStaticfun isEmpty5(str: String): Boolean {return "" == str}}
}

5、静态工具类的实现:

上面我们知道被object关键字修饰的类,都是静态类,类的内部的方法和变量都是静态方法和变量,这样我们就可以通过类名,来直接调用这些方法了,但是需要注意的是:object修饰的类是静态内部类,它的名字是无法和文件类是一样的,所以他在java 中调用的时候是:(文件名+静态内部类名+方法名)

工具类:StringUtils

//它的文件名是StringUtils,所以OusideUtils是无法和文件名一样的
object OusideUtils {fun isEmpty2(str: String): Boolean {return "" == str}@JvmStaticfun isEmpty3(str: String): Boolean {return "" == str}
}class StringUtils{object InsideUtils {fun isEmpty(str: String): Boolean {return "" == str}@JvmStaticfun isEmpty1(str: String): Boolean {return "" == str}}companion object{fun isEmpty4(str: String): Boolean {return "" == str}@JvmStaticfun isEmpty5(str: String): Boolean {return "" == str}}}

kotlin中调用工具类方法

注意:前面我们讲过被@JvmStatic注解的方法是可以当做静态方法来直接被调用的。但是好想在kotlin中调用的话,注不注解都是一样的效果

1、kotlin中直接调用StringUtils类名外的静态内部类的方法,是可以直接用OusideUtils类名+方法方式调用的,但是这样我们无法很明确的知道它的文件名是哪个。

2、调用StringUtils类名内的静态内部类方法的话,需要用  外部类名+静态内部类名+方法名的形式,会有点繁琐

3、用伴生对象的话,就可以实现直接用 外部类名+方法名的形式来实现调用

class TestMain {fun testStringUtils() {//类名内的静态内部类val isEmpty =  StringUtils.InsideUtils.isEmpty("小子")val isEmpty1 = StringUtils.InsideUtils.isEmpty1("")//类名外的静态内部类val isEmpty2 = OusideUtils.isEmpty2("小子2")val isEmpty3 = OusideUtils.isEmpty3("")//伴生对象val isEmpty4 = StringUtils.isEmpty4("小子4")val isEmpty5 = StringUtils.isEmpty5("")println("isEmpty=$isEmpty")println("isEmpty1=$isEmpty1")println("isEmpty2=$isEmpty2")println("isEmpty3=$isEmpty3")println("isEmpty4=$isEmpty4")println("isEmpty5=$isEmpty5")}
}fun main() {val testMain= TestMain()testMain.testStringUtils()
}

Java中调用工具类方法

注意:可以看到当Java调用kotlin的静态工具类的时候,@JvmStatic注解的作用就显示了出来,没被注解的方法都需要调用它们各自的匿名对象来调用各自的方法,被注解的方法,就可以实现用类名+方法名的方式来实现和Java中静态工具类的相同方式。

public class TestJava {public static void main(String[] args) {//调用StringUtils类内部的匿名静态类的方法boolean isEmpty = StringUtils.InsideUtils.INSTANCE.isEmpty("小子");boolean isEmpty1 = StringUtils.InsideUtils.isEmpty1("");//调用StringUtils类外部的匿名静态类的方法boolean isEmpty2 = OusideUtils.INSTANCE.isEmpty2("小子2");boolean isEmpty3 = OusideUtils.isEmpty3("");//调用StringUtils的伴生对象的静态方法boolean isEmpty4 = StringUtils.Companion.isEmpty4("小子4");boolean isEmpty5 = StringUtils.isEmpty5("");System.out. println("isEmpty="+isEmpty);System.out. println("isEmpty1="+isEmpty1);System.out. println("isEmpty2="+isEmpty2);System.out. println("isEmpty3="+isEmpty3);System.out. println("isEmpty4="+isEmpty4);System.out. println("isEmpty5="+isEmpty5);}}

6、单例的实现

方案一:在前面我们讲过,在kotlin中通过object 创建匿名内部类的方式可以实现单例的模式,我们在Java中调用他的内部方法的时候,就可以看到会出现一个INSTANCE 的关键字,其实这个就是这个匿名内部类的单例对象。

public class TestJava {public static void main(String[] args) {//调用StringUtils类内部的匿名静态类的方法boolean isEmpty = StringUtils.InsideUtils.INSTANCE.isEmpty("小子")//调用StringUtils类外部的匿名静态类的方法boolean isEmpty2 = OusideUtils.INSTANCE.isEmpty2("小子2");//调用StringUtils的伴生对象的静态方法boolean isEmpty4 = StringUtils.Companion.isEmpty4("小子4");   }}

方案二:我们这里还有一种比较推荐的单例模式的书写方式

class SingleClass private constructor() {companion object {fun get(): SingleClass {return Holder.instance}}private object Holder {val instance = SingleClass()}
}