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

synthetic fields

synthetic method

synthetic class

概述

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

image

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

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

synthetic fields

非常常见的一个例子

public class Father {

class Son {

}

}

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

image

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

Class clazz = Father.Son.class;

Field[] declaredFields = clazz.getDeclaredFields();

for (Field declaredField : declaredFields) {

System.out.println(declaredField.getName() + ":" + declaredField.isSynthetic());

}

this$0:true

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

Class 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;

}

}

image

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

Class 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 文件

image

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

image

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

我们再看看 Father03$Son.class

image

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

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

image

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

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

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

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

相关文章

java synthetic field_Java synthetic相关推荐

  1. Java中的synthetic详解

    https://blog.csdn.net/moakun/article/details/80577702 synthetic介绍 有synthetic标记的field和method是class内部使 ...

  2. java中的synthetic

    有synthetic标记的field和method是class内部使用的,正常的源代码里不会出现synthetic field.小颖编译工具用的就是jad.所有反编译工具都不能保证完全正确地反编译cl ...

  3. java的synthetic_java synthetic关键字

    有synthetic标记的field和method是class内部使用的,正常的源代码里不会出现synthetic field.小颖编译工具用的就是jad.所有反编译工具都不能保证完全正确地反编译cl ...

  4. java 反射field_java – 使用反射获取Field的泛型类型

    有没有办法在 Java中获取字段的泛型类型? 我有以下对象变量: protected ScheduleView scheduleLine1; protected ScheduleView schedu ...

  5. java calendar field_Java Calendar详解

    一:字段和方法的信息 YEAR 字段: public static final int YEAR ; 指示年的 get 和 set 的字段数字.这是一个特定于日历的值: get 方法: public ...

  6. java反射field_java反射field用法

    我们在前面的文章中学习了java反射机制是什么的问题,相信大家对反射机制有了全面的理解.在java中使用反射机制,会提高程序的灵活性和扩展性,还能节省资源,因此在java编程中使用好反射是重要的.今天 ...

  7. java 反射field_Java基础--反射之Field

    一.Field (1)Field /** * Field: 分装了字段的信息 * 1. 获取字段 * 1.1 Field[] fields = clazz.getDeclaredFields(); * ...

  8. 【读码JDK】Java synthetic的介绍

    这篇是网上找的,感觉还是靠谱一点的文章. 读完这篇文章你将会收获到 synthetic fields synthetic method synthetic class 概述 枚举编译成 class 文 ...

  9. java synthetic_浅谈Java编程中的synthetic关键字

    导读 正文 java synthetic关键字.有synthetic标记的field和method是class内部使用的,正常的源代码里不会出现synthetic field.小颖编译工具用的就是ja ...

最新文章

  1. Oracle 11g R2 RAC 高可用连接特性
  2. Winform中导出Excel数据量百万级的处理办法-导出为csv文件
  3. 【133】常见问题解答
  4. OBJECT_ID()的使用方法
  5. python可视化拖拽平台_python 有没有类似 VS 那种可以拖拽界面的 IDE?
  6. 纯后处理的volumetric light
  7. Mybatis框架相关知识讲解
  8. urlencode编码问题(以及urlparse)
  9. Android 热修复的相关总结(主要是阿里百川的)
  10. 最快的 java 图像_java – 最快的性能过滤图像
  11. linux如何撤销权限修改,linux 撤销权限
  12. 如何用Excel快速制作甘特图?(超详细!)
  13. 教麦叔了解EMC、EMI、EMS的区别
  14. java文章采集爬虫代码示例
  15. xmanager 修改linux ip,Linux配置XManager
  16. 计算机应用基础18秋在线作业2奥鹏,奥鹏15春北航《计算机应用基础》在线作业2答案...
  17. 大数据变现的九种商业模式
  18. 数字图像处理之图像锐化算法
  19. spring3.2入门到大神(备java基础、jsp、servlet,javaee精髓)-任亮-专题视频课程
  20. mysql导入dat文件_后缀名为dat的文件肿么导入到sql数据库

热门文章

  1. suse 调整分区_【suse】挂载硬盘,磁盘分区方法
  2. 基于CMMI模型实现自己的总体研发框架(1)——CMMI模型-前言+概念+通用目标通用实践
  3. 张小庆,在路上(4)-从哪里开始呢
  4. Day9-2021.1.17-剑指offer的八道二叉树题目的整理。涉及递归调用+广度优先遍历。
  5. linux中启动tomcat后浏览器无法访问的解决方法之防火墙关闭
  6. Practical Web Penettation Testing (the first one Mutillidae 大黄蜂 之二)
  7. 博奥智源,无线教学管理系统开发技术详解
  8. Idea 设置类、方法注释模板(解决params和return显示问题)---不来虚的 实测有效
  9. fork join、fork join_any、fork join_none的区别
  10. ​分散式污水处理站远程在线监测