Kotlin 重载 JvmOverloads

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mengks1987/article/details/84143804

首先我们要明确一点就是Kotlin中是没有重载的,那为什么会有JvmOverloads注解呢?其实JvmOverloads注解是为了兼容java的
Java中我们是这样重载的:

	void add(int a){}
    void add(int a,int b){}
    void add(int a,int b,int c){}
    void add(int a,int b,int c,int d){}
    void add(int a,int b,int c,int d,int e){}

我们实际上就是给没有的参数给一个默认的参数,最终调用到参数最多的方法,Kotin中如何写这些方法呢,一个方法足以:

fun add(a: Int,b:Int=0,c:Int=0,d:Int=0,e:Int=0) {}

Kotlin中是可以给参数默认值的,所以Kotlin不需要重载。有人说我的重载调用不同逻辑的,那请你重新命名个方法名。来个我们使用比较多的情况,自定义View时我们要重载4个构造函数,Java是这样实现的:

public class TestView extends View {
    public TestView(Context context) {
        this(context,null);
    }

    public TestView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr,0);
    }

    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
}

Kotlin中非常简单:

class PieChart @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0) : View(context, attrs, defStyleAttr, defStyleRes) {
}

如果你不兼容Java, @JvmOverloads是可以省略的。

我来看下@JvmOverloads的说明:

/**
 * Instructs the Kotlin compiler to generate overloads for this function that substitute default parameter values.
 *
 * If a method has N parameters and M of which have default values, M overloads are generated: the first one
 * takes N-1 parameters (all but the last one that takes a default value), the second takes N-2 parameters, and so on.
 */
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR)
@Retention(AnnotationRetention.BINARY)
@MustBeDocumented
public annotation class JvmOverloads

JvmOverloads的作用是给有默认值的参数生成重载
我们看下有JvmOverloads和没有JvmOverloads的却别

class Overloads {
    fun add(a: Int,b:Int=0) {}
}

生成Java:

public final class Overloads {
   public final void add(int a, int b) {
   }

   // $FF: synthetic method
   // $FF: bridge method
   public static void add$default(Overloads var0, int var1, int var2, int var3, Object var4) {
      if ((var3 & 2) != 0) {
         var2 = 0;
      }

      var0.add(var1, var2);
   }
}

我们发现只有一个2个参数的方法,在Java中调用:

void test(){
        new Overloads().add(0); //编译不过去
    }

但在Kotlin中是可以的。

下面是有JvmOverloads的:

扫描二维码关注公众号,回复: 4258620 查看本文章
public final class Overloads {
   @JvmOverloads
   public final void add(int a, int b) {
   }

   // $FF: synthetic method
   // $FF: bridge method
   @JvmOverloads
   public static void add$default(Overloads var0, int var1, int var2, int var3, Object var4) {
      if ((var3 & 2) != 0) {
         var2 = 0;
      }

      var0.add(var1, var2);
   }

   @JvmOverloads
   public final void add(int a) {
      add$default(this, a, 0, 2, (Object)null);
   }
}

我们发现在加上@JvmOverloads转成Java会生成相应的重载方法。

总结:
1、@JvmOverloads是兼容Java调用Kotlin有默认参数方法的。

猜你喜欢

转载自blog.csdn.net/mengks1987/article/details/84143804