Java synthetic

简介: 读完这篇文章你将会收获到• synthetic fields• synthetic method• synthetic class

读完这篇文章你将会收获到

  • synthetic fields
  • synthetic method
  • synthetic class


概述


上一篇 Java 枚举 提及到编译成 class 文件之后、编译器会在枚举类里帮我们生成一个 VALUES 的静态数组 , 这种编译器生成的都有一个 flag 叫做 synthetic

那么 synthetic 的定义是什么、什么情况下才会有这个 flag ?

由编译器生成的,在源代码中没有出现的,都会被标记为 synthetic。当然有一些例外的情况:默认的构造函数、类的初始化方法、以及枚举类中的 valuevalueOf 方法


synthetic fields

非常常见的一个例子

public class Father {
 class Son {
 }
}
复制代码


我们都知道在一个内部类中,可以直接访问外部类的属性和方法,因为在内部类中是存在一个外部类的一个引用变量,而这个引用变量即是编译器帮我们生成的、也就是一个 synthetic 的属性


我们再写一个测试来验证下

Class<Father.Son> clazz = Father.Son.class;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
   System.out.println(declaredField.getName() + ":" + declaredField.isSynthetic());
}
复制代码
this$0:true
复制代码


我们再来验证一下上一篇文章 Java 枚举 的枚举类

Class<BehaviorEnum> clazz = BehaviorEnum.class;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
   System.out.println(declaredField.getName() + ":" + declaredField.isSynthetic());
}
复制代码
FOLLOW:false
WOW:false
FORWARD_TO_FRIENDS:false
ADD_TO_FAVORITES:false
$VALUES:true
复制代码


synthetic method

我们再来看看被 synthetic 修饰的方法吧

public class Father {
   class Son {
      private String name;
   }
   /**
    * just for test synthetic
    * @return
    */
   public String getName() {
      // just for test synthetic
      return new Son().name;
   }
}
复制代码


Son 类中突然多出了这么一个方法。因为其实 name 属性是一个私有方法、外部类 Father 中却能直接访问这个属性、对于我们写代码来说、这是非常合理的一个事情、但是这都是编译器默默的付出、为我们生成了一个静态的 package 范围的方法、参数就是 Son 的实例、返回值就是 String

Class<Father.Son> sonClass = Father.Son.class;
Method[] declaredMethods = sonClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
    System.out.println(
            Modifier.toString(declaredMethod.getModifiers()) +
                    ":" + declaredMethod.getName() +
                    ":" + declaredMethod.isSynthetic());
}
复制代码
static:access$000:true
复制代码


synthetic class


我们再来看看被 synthetic 修饰的 class

public class Father03 {
    public Son generateSon() {
        return new Son();
    }
    private class Son{
    }
}
复制代码


然后我们编译为 class 文件


发现多出来一个匿名类 Father03$1.class 这个是什么鬼鬼


这个类完全是一个空的类、父类直接是 Object、也没额外定义一些自己的方法

我们再看看 Father03$Son.class


发现它居然有两个构造方法,一个带参数的 package scope 的构造参数是编译器生成的。参数是 Father03Father03$1

我们再看看 Father03 里面的 generateSon 方法

发现它调用的是那个带参数的构造方法,并且参数 Father03$1 的值是为 null

根据上面的种种信息来看、我们可以这么认为、对于一个 private 的内部类(其构造函数默认也是 private ) , 外部类也是无法直接去创建它的实例的、其实换句话来说、对于类的定义来说、不管你是作为一个内部类定义在另一个类中、还是单独定义在一个 java 文件,java 的可见性都是起效的。至于为啥可以在外部内直接创建一个 private 的类的实例、无外乎就是 java 编译器帮我们做了一些额外的工作。


回到上面的例子中、因为 Father03$Son. 只有一个私有的构造函数、而为了能在 Father03 中去创建这么一个 Father03$Son 对象,编译器不得不为我们生成一个 package scope 的构造函数、而午餐的构造函数已经存在了、那编译器只能创建一个有参的构造函数啊、那么问题来了、这个参数的类型应该是啥、那就生成一个类呗、专门为这个参数用。而调用这个构造函数的时候、就直接传给 null 值给它

所以说 Father03$1 作用无外乎可能就是作为一个参数的类型被用到



目录
相关文章
|
1月前
|
Java
java
e是java运行时的环境,包含jvm和运行时所需要的类库 jdk是java开的程序包,包含jre和开发人员使用的工具 jvm就是我们常说的java虚拟机,他是整个java实现跨平台的最核心 的部分,所有的java程序会首先被编译为.class的类文件,这种类文 件可以在虚拟机上执行。也就是说class并不直接与机器的操作系统 相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释 给本地系统执行。 只有jvm还不能成class的执行,因为再解释class的时候jvm需要调用 解释所需要的类库lib,而jre包含lib类库。jvm屏蔽了与具体操作系 统平台相关的信息,使得java程序只需
12 0
|
8月前
|
小程序 Java 编译器
初识java(下)
初识java(下)
64 0
|
7月前
|
Java
学JAVA,从现在开始-day03
每日记录自己学习java的心得和体会~
|
10月前
|
存储 算法 Java
认识java
认识java
81 0
|
存储 固态存储 Java
JAVA问答13
JAVA问答13
96 0
|
Java
Java常见的坑(二)
你猜上述程序输出的是什么? 是 ABC easy as 123 吗? 你执行了输出操作,你才发现输出的是 ABC easy as [C@6e8cf4c6 ,这么一串丑陋的数字是什么鬼? 实际上我们知道字符串与任何数值的相加都会变为字符串,上述事例也不例外, numbers输出其实实际上是调用了Object.toString()方法,让numbers转变为'[c' + '@' + 无符号的十六进制数。
43 0
1101 B是A的多少倍(JAVA)
设一个数 A 的最低 D 位形成的数是 ad​。如果把 ad​ 截下来移到 A 的最高位前面,就形成了一个新的数 B。B 是 A 的多少倍?例如将 12345 的最低 2 位 45 截下来放到 123 的前面,就得到 45123,它约是 12345 的 3.66 倍。
 1101 B是A的多少倍(JAVA)
1100 校庆(JAVA)
2019 年浙江大学将要庆祝成立 122 周年。为了准备校庆,校友会收集了所有校友的身份证号。现在需要请你编写程序,根据来参加校庆的所有人士的身份证号,统计来了多少校友。
1100 校庆(JAVA)
|
安全 Oracle Java
Java小史:从1到5
介绍Java从1到5的版本变化
181 0
|
分布式计算 Oracle Java
赶快看看Java11,不然你就out了!
由于直接从Java8跨越到Java11,所以特性介绍就把Java9-Java11的部分特性一起介绍一下。想要了解Java8特性的朋友可以去我的博客找「Java8系列」。
593 3