java synthetic field_Java synthetic
读完这篇文章你将会收获到
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相关推荐
- Java中的synthetic详解
https://blog.csdn.net/moakun/article/details/80577702 synthetic介绍 有synthetic标记的field和method是class内部使 ...
- java中的synthetic
有synthetic标记的field和method是class内部使用的,正常的源代码里不会出现synthetic field.小颖编译工具用的就是jad.所有反编译工具都不能保证完全正确地反编译cl ...
- java的synthetic_java synthetic关键字
有synthetic标记的field和method是class内部使用的,正常的源代码里不会出现synthetic field.小颖编译工具用的就是jad.所有反编译工具都不能保证完全正确地反编译cl ...
- java 反射field_java – 使用反射获取Field的泛型类型
有没有办法在 Java中获取字段的泛型类型? 我有以下对象变量: protected ScheduleView scheduleLine1; protected ScheduleView schedu ...
- java calendar field_Java Calendar详解
一:字段和方法的信息 YEAR 字段: public static final int YEAR ; 指示年的 get 和 set 的字段数字.这是一个特定于日历的值: get 方法: public ...
- java反射field_java反射field用法
我们在前面的文章中学习了java反射机制是什么的问题,相信大家对反射机制有了全面的理解.在java中使用反射机制,会提高程序的灵活性和扩展性,还能节省资源,因此在java编程中使用好反射是重要的.今天 ...
- java 反射field_Java基础--反射之Field
一.Field (1)Field /** * Field: 分装了字段的信息 * 1. 获取字段 * 1.1 Field[] fields = clazz.getDeclaredFields(); * ...
- 【读码JDK】Java synthetic的介绍
这篇是网上找的,感觉还是靠谱一点的文章. 读完这篇文章你将会收获到 synthetic fields synthetic method synthetic class 概述 枚举编译成 class 文 ...
- java synthetic_浅谈Java编程中的synthetic关键字
导读 正文 java synthetic关键字.有synthetic标记的field和method是class内部使用的,正常的源代码里不会出现synthetic field.小颖编译工具用的就是ja ...
最新文章
- Oracle 11g R2 RAC 高可用连接特性
- Winform中导出Excel数据量百万级的处理办法-导出为csv文件
- 【133】常见问题解答
- OBJECT_ID()的使用方法
- python可视化拖拽平台_python 有没有类似 VS 那种可以拖拽界面的 IDE?
- 纯后处理的volumetric light
- Mybatis框架相关知识讲解
- urlencode编码问题(以及urlparse)
- Android 热修复的相关总结(主要是阿里百川的)
- 最快的 java 图像_java – 最快的性能过滤图像
- linux如何撤销权限修改,linux 撤销权限
- 如何用Excel快速制作甘特图?(超详细!)
- 教麦叔了解EMC、EMI、EMS的区别
- java文章采集爬虫代码示例
- xmanager 修改linux ip,Linux配置XManager
- 计算机应用基础18秋在线作业2奥鹏,奥鹏15春北航《计算机应用基础》在线作业2答案...
- 大数据变现的九种商业模式
- 数字图像处理之图像锐化算法
- spring3.2入门到大神(备java基础、jsp、servlet,javaee精髓)-任亮-专题视频课程
- mysql导入dat文件_后缀名为dat的文件肿么导入到sql数据库
热门文章
- suse 调整分区_【suse】挂载硬盘,磁盘分区方法
- 基于CMMI模型实现自己的总体研发框架(1)——CMMI模型-前言+概念+通用目标通用实践
- 张小庆,在路上(4)-从哪里开始呢
- Day9-2021.1.17-剑指offer的八道二叉树题目的整理。涉及递归调用+广度优先遍历。
- linux中启动tomcat后浏览器无法访问的解决方法之防火墙关闭
- Practical Web Penettation Testing (the first one Mutillidae 大黄蜂 之二)
- 博奥智源,无线教学管理系统开发技术详解
- Idea 设置类、方法注释模板(解决params和return显示问题)---不来虚的 实测有效
- fork join、fork join_any、fork join_none的区别
- ​分散式污水处理站远程在线监测