Scala学习笔记-apply方法

Scala是一种基于JVM的静态类型语言,其apply方法提供了一种灵活性。当对象接收参数时,Scala会转换为apply方法调用。apply方法可以在class或object中定义,编译后在class中它指向具体对象,在object中则与单例对象相关联。通过编译后的源码,我们可以看到apply方法如何在单例对象上被调用。

Scala-apply方法

参考:lyrebing的优快云博客

这里写图片描述

Scala是一种构建在JVM之上的静态类型脚本语言,而脚本语言会有一些约定来增强灵活性,下面看两条在日常开发中常见的约定:

约定1:在明确了调用者的前提下,若方法只有一个参数,则调用时就可以省略括号,例如0 to 2的完整调用是0.to(2),但是println(10)就不能简写成 println 10,因为没有明确方法的调用者。


约定2:用括号给一个变量(对象)传递参数时,scala会把它转换成对apply方法的调用。

apply方法可以定义在class中,也可以定义在object中,这两种方式有所区别,但本质是一样的,下面列举一个简单是示例来说明apply方法的用法。

  • 在class中定义apply方法
class ApplyTest{
    def apply() = println("I am into spark so much!!!")
    def apply(p: String) = println("apply with one param:" + p)
    def haveATry: Unit ={
        println("have a try on apply")
    }
}

object ApplyOperation{
     def main (args: Array[String]) {
         val array= Array(1,2,3,4)
         val a = new ApplyTest() 

         a.haveATry
         a()  //调用无参apply
         a("adsffdsa") //调用带参数的apply
    }
}

根据约定,我们用括号想对象中传递参数,scala编译器会将其转换成对apply方法的调用,需要注意的是class中的apply方法指向具体的对象。

编译后的部分代码如下:

public final class ApplyOperation$
{
  public static final  MODULE$;

  static
  {
    new ();
  }

  public void main(String[] args)
  {
    int[] array = { 1, 2, 3, 4 };
    ApplyTest a = new ApplyTest();
    //此处是关键
    a.haveATry();
    a.apply();
    a.apply("adsffdsa");
  }
  private ApplyOperation$() { MODULE$ = this;
  }
}
  • 在object中定义apply方法
    在前面讲过,被object定义出来的是一个static final的单例对象,那么一个被定义在object中的apply方法与这个单例对象之间有什么联系呢?先看代码示例
class ApplyTest{
    def apply() = println("I am into spark so much!!!")
    def apply(p: String) = println("apply with one param:" + p)
    def haveATry: Unit ={
        println("have a try on apply")
    }
}

object ApplyTest {

    def apply(a: String, b: String) = {
        println(a + ",," + b)
    }
}

object ApplyOperation{
     def main (args: Array[String]) {
         val a = ApplyTest("s","n")  
    }
}

由于ApplyTest是一个单例对象,所以,按照约定,用括号向对象中传递参数时,会调用apply方法。对于上面的示例,就是在单例对象ApplyTest上调用apply(a,b)方法,可以通过编译后的源码来验证这一点

import scala.runtime.BoxedUnit;

public final class ApplyOperation$
{
  public static final  MODULE$;

  static
  {
    new ();
  }

  public void main(String[] args)
  {
    //此处是重点
    ApplyTest..MODULE$.apply("s", "n"); BoxedUnit a = BoxedUnit.UNIT;
  }
  private ApplyOperation$() { MODULE$ = this;
  }
}

从上面的代码中可以看出,确实是在单例对象 MODULE$上调用的apply方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值