slf4j 桥接与被桥接_合成和桥接方法

slf4j 桥接与被桥接

如果您曾经玩过反射并执行了getDeclaredMethods()您可能会感到惊讶。 您可能会获得源代码中不存在的方法。 或者,也许您看了一些方法的修饰符,发现其中一些特殊方法是易变的。 顺便说一句:对于Java采访来说,这是一个令人讨厌的问题,“当方法易变时,这意味着什么?” 正确的答案是方法不能是易变的。 同时,在getDeclaredMethods()甚至getMethods()返回的方法中可能存在某些方法,对于这些方法, Modifier.isVolatile(method.getModifiers())为true。

这是项目转换器的用户之一发生的 。 他意识到,交换器(本身会深入挖掘Java的黑暗细节)生成的Java源代码无法使用关键字volatile作为方法的修饰符进行编译。 结果,它也不起作用。

那里发生了什么事? 桥接和合成方法是什么?

能见度

创建嵌套或嵌入式类时,可以从顶级类访问嵌套类的私有变量和方法。 这由不可变的嵌入式构建器模式使用 。 这是语言规范中定义的Java的明确定义的行为。

JLS7,6.6.1确定可访问性

…如果成员或构造函数被声明为私有,则访问为
当且仅当它出现在顶级类的主体中时才允许(第7.6节)
包含成员或构造函数的声明…

package synthetic;public class SyntheticMethodTest1 {private A aObj = new A();public class A {private int i;}private class B {private int i = aObj.i;}public static void main(String[] args) {SyntheticMethodTest1 me = new SyntheticMethodTest1();me.aObj.i = 1;B bObj = me.new B();System.out.println(bObj.i);}
}

JVM如何处理它? JVM不知道内部或嵌套类。 对于JVM,所有类都是顶级外部类。 所有类都被编译为顶级类,这就是那些不错的方法...$. .class ...$. .class文件已创建。

$ ls -Fart
../                         SyntheticMethodTest2$A.class  MyClass.java  SyntheticMethodTest4.java  SyntheticMethodTest2.java
SyntheticMethodTest2.class  SyntheticMethodTest3.java     ./            MyClassSon.java            SyntheticMethodTest1.java

如果创建嵌套或内部类,它将被编译为完整的顶级类。

外层如何提供私有字段? 如果这些人进入了真正的顶级阶层并且是私人的,那么他们如何从外部阶层得到呢?

javac解决此问题的方式是,对于任何私有字段但从顶级类使用的字段,方法或构造函数,它都会生成综合方法。 这些合成方法用于到达原始私有字段/方法/构造函数。 这些方法的生成以巧妙的方式完成:仅生成真正需要并从外部使用的那些方法。

package synthetic;import java.lang.reflect.Constructor;
import java.lang.reflect.Method;public class SyntheticMethodTest2 {public static class A {private A(){}private int x;private void x(){};}public static void main(String[] args) {A a = new A();a.x = 2;a.x();System.out.println(a.x);for (Method m : A.class.getDeclaredMethods()) {System.out.println(String.format("%08X", m.getModifiers()) + " " + m.getName());}System.out.println("--------------------------");for (Method m : A.class.getMethods()) {System.out.println(String.format("%08X", m.getModifiers()) + " " + m.getReturnType().getSimpleName() + " " + m.getName());}System.out.println("--------------------------");for( Constructor<?> c : A.class.getDeclaredConstructors() ){System.out.println(String.format("%08X", c.getModifiers()) + " " + c.getName());}}
}

由于生成的方法的名称取决于实现方式,因此不能保证对上述程序的输出最多的是,在我执行该程序的特定平台上,它会产生以下输出:

2
00001008 access$1
00001008 access$2
00001008 access$3
00000002 x
--------------------------
00000111 void wait
00000011 void wait
00000011 void wait
00000001 boolean equals
00000001 String toString
00000101 int hashCode
00000111 Class getClass
00000111 void notify
00000111 void notifyAll
--------------------------
00000002 synthetic.SyntheticMethodTest2$A
00001000 synthetic.SyntheticMethodTest2$A

在上面的程序中,我们为字段x赋值,并且还调用了相同名称的方法。 这些是触发编译器生成综合方法所必需的。 您可以看到它生成了三种方法,大概是字段x的setter和getter以及方法x()的综合方法。 但是,这些综合方法未在getMethods()返回的下一个列表中列出,因为它们是综合方法,因此不适用于通用调用。 从这个意义上讲,它们是私有方法。

十六进制数字可以用作解释器,查看类java.lang.reflect.Modifier定义的常量:

00001008 SYNTHETIC|STATIC
00000002 PRIVATE
00000111 NATIVE|FINAL|PUBLIC
00000011 FINAL|PUBLIC
00000001 PUBLIC
00001000 SYNTHETIC

列表中有两个构造函数。 有一个私人的和一个合成的。 私有存在,因为我们定义了它。 另一方面,合成的存在是因为我们从外部调用了私有的。 到目前为止,桥接方法还没有。

泛型和继承

到目前为止,还不错,但是我们仍然没有看到任何“易变”的方法。

查看java.lang.reflec.Modifier的源代码,您可以看到常量0x00000040被定义了两次。 一次是VOLATILE ,一次是BRIDGE (后者是私有程序包,不用于一般用途)。

要拥有这样一种方法,一个非常简单的程序就可以做到:

package synthetic;import java.lang.reflect.Method;
import java.util.LinkedList;public class SyntheticMethodTest3 {public static class MyLink extends LinkedList<String> {@Overridepublic String get(int i) {return "";}}public static void main(String[] args) {for (Method m : MyLink.class.getDeclaredMethods()) {System.out.println(String.format("%08X", m.getModifiers()) + " " + m.getReturnType().getSimpleName() + " " + m.getName());}}
}

我们有一个链表,该链表的方法get(int)返回String 。 我们不要讨论干净的代码问题。 这是演示该主题的示例代码。 干净的代码中也会出现同样的问题,尽管更复杂,更难在出现问题时解决。

输出显示:

00000001 String get
00001041 Object get

我们有两个get()方法。 一个出现在源代码中,另一个出现在源代码中并且是合成的。 反编译器javap表示生成的代码是:

public java.lang.String get(int);Code:Stack=1, Locals=2, Args_size=20:   ldc     #2; //String2:   areturnLineNumberTable:line 12: 0public java.lang.Object get(int);Code:Stack=2, Locals=2, Args_size=20:   aload_01:   iload_12:   invokevirtual   #3; //Method get:(I)Ljava/lang/String;5:   areturn

有趣的是,这两种方法的签名是相同的,只是返回类型不同。 JVM允许这样做,即使Java语言无法做到这一点。 bridge方法不执行其他任何操作,而是调用原始方法。

为什么需要这种合成方法? 谁来使用它。 例如,想要使用类型MyLink的变量来调用方法get(int)MyLink

List<?> a = new MyLink();Object z = a.get(0);

它不能调用返回String的方法,因为List没有这样的方法。 为了使其更具说明性,让我们重写方法add()而不是get()

package synthetic;import java.util.LinkedList;
import java.util.List;public class SyntheticMethodTest4 {public static class MyLink extends LinkedList<String> {@Overridepublic boolean add(String s) {return true;}}public static void main(String[] args) {List a = new MyLink();a.add("");a.add(13);}
}

我们可以看到桥接方法

public boolean add(java.lang.Object);Code:Stack=2, Locals=2, Args_size=20:   aload_01:   aload_12:   checkcast       #2; //class java/lang/String5:   invokevirtual   #3; //Method add:(Ljava/lang/String;)Z8:   ireturn

不仅叫原版。 它还检查类型转换是否正确。 这是在运行时完成的,而不是由JVM本身完成的。 如您所料,它确实出现在第18行中:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Stringat synthetic.SyntheticMethodTest4$MyLink.add(SyntheticMethodTest4.java:1)at synthetic.SyntheticMethodTest4.main(SyntheticMethodTest4.java:18)

下次在面试中遇到关于不稳定方法的问题时,您可能比面试官了解的更多。

参考: Java Deep博客中JCG合作伙伴 Peter Verhas的合成方法和桥接方法 。

翻译自: https://www.javacodegeeks.com/2014/03/synthetic-and-bridge-methods.html

slf4j 桥接与被桥接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/343023.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

隔离电源模块的5个作用

在工业控制设备中&#xff0c;有时候要求两个系统之间的电源地线隔离&#xff0c;如隔离地线噪声、隔离高共模电压等&#xff0c;采用带变压器的直流变换器&#xff0c;将两个电源之间隔开&#xff0c;使他们相互独立&#xff0c;从而实现以上目的&#xff01;每个隔离电源模块…

[渝粤教育] 广东-国家-开放大学 21秋期末考试基础会计10258k2

1、在登记账簿时&#xff0c;红色墨水不能用于&#xff08;&#xff09;。 &#xff08;2 分&#xff09; A&#xff0e;更正错账 B&#xff0e;记账 C&#xff0e;结账 D&#xff0e;冲账 2、下列凭证中属于自制原始凭证的是&#xff08;  &#xff09;。&#xff08;2 分&a…

html纵向滚动特效,带视觉差效果的垂直全屏整页滚动特效

这是一款效果非常炫酷的带视觉差效果的垂直全屏整页滚动特效。该特效使用jQuery和CSS3完成&#xff0c;用户可以通过滚动鼠标来一次垂直切换一个页面&#xff0c;在页面切换的时候还带有一些视觉差特效。使用方法HTML结构这个特效的HTML结构使用一个作为包裹容器。里面每一个是…

高清监控如何选择交换机

网络监控系统在我国的安防中占据了绝对的位置&#xff0c;在高清网络视频监控系统中&#xff0c;经常有客户反啊馈画面延时、卡顿等现象&#xff0c;造成这种现象的原因有很多&#xff0c;但大多数情况下还是交换机的配置不够合理&#xff0c;导致带宽不足造成的。交换机是整个…

CAN总线知识点概述

CAN全称为“ControllerAreaNetwork”&#xff0c;简称CAN&#xff0c;是国际上应用最广泛的现场总线之一。在当前的汽车产业中&#xff0c;出于对安全性、舒适性、方便性、低公害、低成本的要求&#xff0c;各种各样的电子控制系统被开发出来。出于这些系统之间通信所用的数据类…

[渝粤教育] 广东-国家-开放大学 21秋期末考试工程经济10202k2

1、某设备原始价值16,000元&#xff0c;残值为零&#xff0c;折旧年限为5年&#xff0c;用双倍余额递减法计算的第4年折旧额为&#xff08; &#xff09;元。&#xff08;2.5 分&#xff09; A&#xff0e;1,728 B&#xff0e;1,382.4 C&#xff0e;2,304 D&#xff0e;3,840 2…

使用Java从地图中删除元素

关于从Java中的Map删除元素的非常简短的文章。 我们将专注于删除多个元素&#xff0c;而忽略了您可以使用Map.remove删除单个元素的Map.remove 。 以下Map将用于此帖子&#xff1a; Map<Integer, String> map new HashMap<>(); map.put(1, "value 1")…

[渝粤教育] 广东-国家-开放大学 21秋期末考试建筑工程概预算10326k2

1、构造柱与墙体连接处的马牙槎&#xff0c;从每层柱脚开始&#xff0c;先退后进&#xff0c;沿墙高每&#xff08; &#xff09;设2φ6拉结钢筋。&#xff08;2 分&#xff09; A&#xff0e;700mm B&#xff0e;500mm C&#xff0e;400mm D&#xff0e;600mm 2、项目建设单位…

工业以太网交换机的产品性能有哪些呢?

工业以太网交换机的使用非常广泛&#xff0c;有智能交通、电子警察、平安城市、工厂自动化等&#xff0c;如何在恶劣的室外作业环境中保障数据的稳定传输&#xff0c;对网络和通讯设备提出了极高的适应性要求&#xff0c;那么&#xff0c;工业以太网交换机的产品性能有哪些呢&a…

android 年月日时分秒控件,Android 年月日时分秒时间选择器

项目开发中 如果你需要一个年月日时分秒类型时间选择器 用DataPicker和TimePicker联动去实现得话 会非常得不方便 会碰到布局不协调得问题 灵活性很低 可实现的布局也就两种 所以为了更好的效果 个人建议你使用 numberPicker 数字选择器 去实现 本人思路是 numberpicker结合Pop…

[渝粤教育] 广东-国家-开放大学 21秋期末考试招投标与合同管理10217k2 (2)

1、施工合同中&#xff0c;承包人按照工程师提出的施工进度计划修改建议进行了修改&#xff0c;由于修改后的计划不合理而导致的窝工损失应当由( )承担&#xff08;2 分&#xff09; A&#xff0e;发包人 B&#xff0e;发包人与承包人共同 C&#xff0e;承包人 D&#xff0e;工…

[渝粤教育] 广东-国家-开放大学 21秋期末考试电算化会计10169k2

单项选择题 1、在固定资产核算系统的卡片中&#xff0c;能够唯一确定每项资产的数据项是() &#xff08;2 分&#xff09; A&#xff0e;类别编号 B&#xff0e;规格型号 C&#xff0e;资产名称 D&#xff0e;资产编号 单项选择题 1、在固定资产核算系统的卡片中&#xff0c;能…

工业交换机的单模和多模能否互相替代?

客户在购买工业交换机的时候会被问道是要单模单纤、单模双纤、多模双纤等问题&#xff0c;还有用在什么地方&#xff0c;这些只有自己清楚了解了选购工业交换机时才会明白我们应该选什么类型的产品。但有客户会问工业交换机单模和多模能否互相替代?接下来飞畅科技的小编来给你…

物联网常用的组网方式浅析

一石激起千层浪&#xff0c;现代科技的网络革新可以变换着诸多行业的运作模式&#xff0c;甚至直接改变了我们的生活方式&#xff0c;网络技术与我们不再遥远与陌生。今天&#xff0c;小亿就带大家走近“LoRa”、“Zigbee”、“WIFI”、“NB-IOT”、“蓝牙”&#xff0c;现行常…

[渝粤教育] 广东-国家-开放大学 21秋期末考试财务管理10164k2 (2)

1、信用标准是(   )的重要内容。&#xff08;2 分&#xff09; A&#xff0e;现金折扣政策             B&#xff0e;信用期限 C&#xff0e;信用条件 D&#xff0e;收账政策              2、影响企业短期偿债能力的主要因素是&#xff08; &#…

使用Apache POI插入内容

介绍 大家都知道POI&#xff01; 它是可用Java创建Excel文档的最佳库。 它真的很好&#xff0c;可以轻松地完成很多事情。 但是最近我想做些不那么简单的事情。 我想将现有的xlsx文件用作模板&#xff0c;并在某些位置将一些数据插入其中。 在这篇文章中&#xff0c;我将说明为…

DC/DC电源模块是什么?有何特点

一、电源模块是什么&#xff1f; 电源模块是可以直接安装在印刷电路板上的电源供应器&#xff0c;有降压和升压两种&#xff0c;专用集成电路( ASIC )、数字信号处理器( DSP )、微处理器、存储器、现场可编程门阵列( FPGA )及其他数字或模拟负载提供供电。 二、DC/DC电源模块…

【渝粤教育】 广东开放大学 21秋期末考试组织行为学10068k2

1、组织行为学具有应用性学科性质。&#xff08;3 分&#xff09; 正确 错误 2、微观环境因素一般包括经济、政治、文化、法律和科学技术等。&#xff08;3 分&#xff09; 正确 错误 3、奖励与惩罚相结合&#xff0c;应该以罚为主&#xff0c;以奖为辅。&#xff08;3 分&…

工业交换机的价格为什么有高低之分?

最近&#xff0c;飞畅科技的小编发现客户在工业交换机价格上有很大的争议。为什么这么说呢&#xff1f;有的客户觉得为什么你们家的交换机这么贵&#xff0c;我便宜一半也能买到了&#xff0c;还有客户想花这些钱买这么一个工业交换机真的划算吗&#xff1f;那接下来小编就来和…

【渝粤教育】国家开放大学2018年春季 0221-21T数字电子电路 参考试题

编号&#xff1a;0221 2017-2018学年第二学期期末考试 数字电子电路&#xff08;开卷&#xff09; 试 题 2018年 7月 填空题&#xff08;每小题6分&#xff0c;共30分&#xff09; 1、在直流电路中&#xff0c;电容上的 及电感中的 一般不会突变。 2、NPN硅三极管工作在截止状…