为什么说Scala中public的底层还是private?

了解过Scala的同学应该都知道,Scala中“取消”了许多关键字的使用,例如public,static等;但是这也为我们带来了一些困惑,本文将对其中的一个困惑进行解答:为什么说Scala中public的底层还是private?

  • 类中的属性不用加范围限定符就表示为“public”
    上面这段话,或许在学习Scala的过程中我们都会听过,例如下面这段代码:
object TestClass {
  def main(args: Array[String]): Unit = {
    val instance = new C_0
    println(instance.name)  // hello
  }
}

class C_0() {
  val name: String = "hello"
}

上面这段代码中,对于类C_0的属性name我们没有加任何限定符,但是在主程序中,通过创建的对象我们仍然可以通过.name的方式对对象的属性进行直接的访问,这样看起来与Java中的public限定的属性似乎是没有区别的。但事实果真如此吗?

  • Scala对public的理解:
    对上面那段代码的类C_0进行反编译,我们可以得到如下内容:
//decompiled from C_0.class
package com.PinkGranite.sparkCore;

import scala.reflect.ScalaSignature;

@ScalaSignature(
   bytes = "\u0006\u0001\u00152A\u0001B\u0003\u0001\u0019!)1\u0003\u0001C\u0001)!9q\u0003\u0001b\u0001\n\u0003A\u0002B\u0002\u0013\u0001A\u0003%\u0011DA\u0002D?BR!AB\u0004\u0002\u0013M\u0004\u0018M]6D_J,'B\u0001\u0005\n\u0003-\u0001\u0016N\\6He\u0006t\u0017\u000e^3\u000b\u0003)\t1aY8n\u0007\u0001\u0019\"\u0001A\u0007\u0011\u00059\tR\"A\b\u000b\u0003A\tQa]2bY\u0006L!AE\b\u0003\r\u0005s\u0017PU3g\u0003\u0019a\u0014N\\5u}Q\tQ\u0003\u0005\u0002\u0017\u00015\tQ!\u0001\u0003oC6,W#A\r\u0011\u0005i\tcBA\u000e !\tar\"D\u0001\u001e\u0015\tq2\"\u0001\u0004=e>|GOP\u0005\u0003A=\ta\u0001\u0015:fI\u00164\u0017B\u0001\u0012$\u0005\u0019\u0019FO]5oO*\u0011\u0001eD\u0001\u0006]\u0006lW\r\t"
)
public class C_0 {
   private final String name = "hello";

   public String name() {
      return this.name;
   }
}

从这里我们就可以看出一些端倪了,事实上,name属性仍然是private类型,但是同时还增加了一个name()方法,该方法实现的功能类似于get方法(也就是传回name属性的值),而我们又知道,在Scala中,如果方法没有参数可以直接省略括号,这样的话就变成了instance.name,表现出了该属性为public的错觉!

  • 进一步探究Scala中对private属性的解读:
    请看下面这一段代码:
class User_(age: Int) {
  private var myAge: Int = age
}

对它进行反编译,得到如下结果:

//decompiled from User_.class
package com.PinkGranite.sparkCore;

import scala.reflect.ScalaSignature;

@ScalaSignature(
   bytes = "\u0006\u0001!2AAB\u0004\u0001\u001d!AQ\u0003\u0001B\u0001B\u0003%a\u0003C\u0003\u001a\u0001\u0011\u0005!\u0004C\u0004\u001f\u0001\u0001\u0007I\u0011B\u0010\t\u000f\u0001\u0002\u0001\u0019!C\u0005C!1q\u0005\u0001Q!\nY\u0011Q!V:fe~S!\u0001C\u0005\u0002\u0013M\u0004\u0018M]6D_J,'B\u0001\u0006\f\u0003-\u0001\u0016N\\6He\u0006t\u0017\u000e^3\u000b\u00031\t1aY8n\u0007\u0001\u0019\"\u0001A\b\u0011\u0005A\u0019R\"A\t\u000b\u0003I\tQa]2bY\u0006L!\u0001F\t\u0003\r\u0005s\u0017PU3g\u0003\r\tw-\u001a\t\u0003!]I!\u0001G\t\u0003\u0007%sG/\u0001\u0004=S:LGO\u0010\u000b\u00037u\u0001\"\u0001\b\u0001\u000e\u0003\u001dAQ!\u0006\u0002A\u0002Y\tQ!\\=BO\u0016,\u0012AF\u0001\n[f\fu-Z0%KF$\"AI\u0013\u0011\u0005A\u0019\u0013B\u0001\u0013\u0012\u0005\u0011)f.\u001b;\t\u000f\u0019\"\u0011\u0011!a\u0001-\u0005\u0019\u0001\u0010J\u0019\u0002\r5L\u0018iZ3!\u0001"
)
public class User_ {
   private int myAge;

   private int myAge() {
      return this.myAge;
   }

   private void myAge_$eq(final int x$1) {
      this.myAge = x$1;
   }

   public User_(final int age) {
      this.myAge = age;
   }
}

可以看到,属性的类型仍然为private类型,但是对应的get类方法myage()的限定符同样变为了private,也就是我们不能直接对其进行引用,差别就发生在这里了!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值