Java陷阱:内部类中的字段访问

这本身不是一个“陷阱”,而是一个值得了解的实现细节。 假设我有一个带有字段的内部类。 这样的字段对于封闭的类是可见的,但是以下哪种方法是访问它的最快方法? 注意! 我只在这里查看生成的字节码,而不考虑任何JIT优化,因此这种“性能分析”非常幼稚
public class Test {public void testAlternatives() {// Alternative 1System.out.println(new Inner().field);// Alternative 2System.out.println(new Inner().getField());// Alternative 3System.out.println(new Inner2().field);// Alternative 4System.out.println(new Inner2().getField());}class Inner {private int field;public int getField() {return field;}}class Inner2 {int field;public int getField() {return field;}}}

一个直观的答案是,替代方案1和3的速度相当快,因为​​该字段始终对封闭的类可见,并且两者都使用字段访问,总体而言,该字段的访问速度比替代方案2和4中使用的方法访问快一点。但是,有一个实现细节导致这是不正确的。 JVM本身没有称为“内部类”的概念。 整个概念由Java编译器实现,并且在字节码级别,所有内容均由普通类组成。

这里的问题是,如果内部类具有私有字段,则编译器最终会将内部类编译为普通类。 普通类中的私有字段不能被其他类访问,因此,封闭的Test类如果没有技巧,就无法“看到”该字段。 这是上面的代码“拒绝”了编译器实际编译为字节码的内容:

public class Test {public void testAlternatives() {// Alternative 1System.out.println(Test$Inner.access$000(new Test$Inner(this)));// Alternative 2System.out.println(new Test$Inner(this).getField());// Alternative 3System.out.println(new Test$Inner2(this).field);// Alternative 4System.out.println(new Test$Inner2(this).getField());}
}class Test$Inner {final Test this$0;private int field;Test$Inner(Test test) {this$0 = test;}public int getField() {return field;}static int access$000(Test$Inner inner) {return inner.field;}}class Test$Inner2 {final Test this$0;int field;Test$Inner2(Test test) {this$0 = test;}public int getField() {return field;}}

如您所见,为了授予对私有字段的访问权限,将生成一个名为access $ 000的程序包级静态访问器方法。 现在,更容易看到替代方法3最有可能成为最快的替代方法,因为它是唯一使用直接字段访问的方法。 在字段中使用程序包访问是一个微优化,但是这绝对是Java开发人员应该知道的一个细节。 在对性能至关重要的代码部分中,这实际上可能很重要,而Android性能指南实际上提到了此实现细节。

当尝试对内部类的空引用进行字段访问时,此实现的详细信息也可能会引起一些混乱。 考虑以下代码:

public class NullTest {class Inner {private int field;}public void test() {Inner inner = null;System.out.println(inner.field);}public static void main(String[] args) {new NullTest().test();}
}

变量“ inner”为空,因此显然会引发NullPointerException。 但是,从原始代码中看不出来的是,异常是在编译器生成的静态访问器方法内引发的!

$ java NullTest
Exception in thread 'main' java.lang.NullPointerExceptionat NullTest$Inner.access$000(NullTest.java:2)at NullTest.test(NullTest.java:8)at NullTest.main(NullTest.java:12)

堆栈跟踪包含直观的异常源(第8行),但是实际源会使不了解编译器生成的访问器方法的开发人员感到困惑。

参考: Java陷阱:来自Jawsy Solutions技术博客博客的JCG合作伙伴 Joonas Javanainen, 内部类中的字段访问 。


翻译自: https://www.javacodegeeks.com/2012/05/java-pitfalls-field-access-in-inner.html

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

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

相关文章

coverity代码检测工具介绍_微服务测试之静态代码扫描

静态代码扫描为整个发展组织增加价值。无论您在开发组织中发挥的作用如何,静态代码扫描解决方案都具有附加价值,拥有软件开发中所需要的尖端功能,最大限度地提高质量并管理软件产品中的风险。背景微服务架构模式具有服务间独立,可…

XML引入以及与html的区别

1.1 引入HTML: 负责网页的结构 CSS&#xff1a; 负责网页的样式&#xff08;美观&#xff09;Javascript&#xff1a; 负责在浏览器端与用户进行交互。负责静态的网页制作的语言HTML语言特点&#xff1a;1&#xff09;由标签组成。 <title> <p> <hr/> <br…

ADF:在任务流终结器中支持bean作用域

介绍 当我们需要在任务流消失之前完成一些最终工作&#xff08;干净的资源&#xff0c;紧密的连接等&#xff09;时&#xff0c;这是使用任务流终结器的非常普遍的推荐做法。 和往常一样&#xff0c;我们使用在任务流中声明的托管bean。 托管Bean可以具有不同的范围-请求&#…

Python 异常处理--raise函数用法

在Python中&#xff0c;要想引发异常&#xff0c;最简单的形式就是输入关键字raise&#xff0c;后跟要引发的异常的名称。异常名称标识出具体的类&#xff1a; Python异常处理是那些类的对象。执行raise语句时&#xff0c;Python会创建指定的异常类的一个对象。raise语句还可指…

大学计算机教学ppt数制,大学计算机基础 第3讲 数制及其相互转换 国家精品课程课件(可编辑)...

大学计算机基础第3讲数制及其相互转换国家精品课程课件PPT第1 章计算机基础知识第3 讲数制及其相互转换主要教学内容数制的基本概念1 数制转换2 小结3 学习目标1 理解数制的基本概念。2 掌握数制间的转换。3 能够灵活应用转换关系完成数制之间的转换。重点与难点不同数制之间的…

linux中匿名用户怎么登陆_南京课工场IT培训:Linux中vsftpd服务配置(匿名,用户,虚拟用户)...

vsftpd概述vsftpd 是“very secure FTP daemon”的缩写&#xff0c;安全性是它的一个最大的特点。vsftpd 是一个 UNIX 类操作系统上运行的服务器的名字&#xff0c;它可以运行在诸如 Linux、BSD、Solaris、 HP-UNIX等系统上面&#xff0c;是一个完全免费的、开放源代码的ftp服务…

Java _ JDK _ Arrays, LinkedList, ArrayList, Vector 及Stack

(最近在看JDK源码&#xff0c;只是拿着它的继承图在看&#xff0c;但很多东西不记录仍然印象不深&#xff0c;所以开始记录JDK阅读系列。) &#xff08;一&#xff09;Arrays Arrays比较特殊&#xff0c;直接继承自Arrays -》List(Interface) -》Collection(Interface)。(Maybe…

server2016做文件服务器,『配置』服务器搭建 Office Online Server2016 实现文档预览 番外 错误篇...

安装一个或多个角色、角色服务或功能失败。找不到源文件。请再次尝试在新的“添加角色和功能”向导会话中安装角色、角色服务或功能&#xff0c;然后在向导的“确认”页中单击“指定备用源路径”以指定安装所需的源文件的有效位置。目标服务器的计算机帐户必须能够访问该位置。…

Java High CPU故障排除指南–第1部分

本文是该系列的第1部分&#xff0c;它将为您提供有关如何进行故障排除和识别Java高CPU问题根本原因的综合指南。 该指南也适用于独立的Java程序&#xff0c;但旨在帮助涉及Java EE企业日常生产支持的个人。 它还将包括最常见的高级CPU问题列表以及高级解决方案。 生产问题解决…

PHP数据结构之三 线性表中的单链表的PHP实现

线性表的链式存储&#xff1a;用一组任意的存储单元存储线性表中的数据元素。用这种方法存储的线性表简称线性链表。 链式存储线性表的特点&#xff1a;存储链表中结点的一组任意的存储单元可以是连续的&#xff0c;也可以是不连续的&#xff0c;甚至是零散分布在内存中的任意位…

php进程间通信 yoc_swoole的process模块创建和使用子进程

swoole中为我们提供了一个进程管理模块 Process&#xff0c;替换PHP的 pcntl 扩展&#xff0c;方便我们创建进程&#xff0c;管理进程&#xff0c;和进程间的通信。swoole提供了2种进程间的通信&#xff1a;1、基于 unix socket 的管道 pipe。2、基于 sysvmsg 的消息队列。我们…

ajax回复留言,Ajax 留言板模拟

这一节我们利用 Ajax 制作一个留言板模拟&#xff0c;之所以叫模拟&#xff0c;是由于没有将留言内容存入数据库&#xff0c;而只是假像地处理&#xff0c;因为这里着重讨论 Ajax&#xff0c;暂时就不涉及数据库操作。这里我们模拟了留言失败的情况&#xff0c;每次提交有 50% …

RabbitMQ:计划邮件传递

本月初&#xff0c;我在ComoRichWeb上的RabbitMQ上做了一个演讲&#xff0c;与会人员提出的一个问题是“是否可以发布一条消息供以后使用&#xff1f;” 我回答说&#xff0c;就我所知&#xff0c;这是不可能的&#xff0c;但是可能会有一些技巧来实现它。 好吧&#xff0c;今天…

mysqls压力测试怎么用_阿里研究员:测试稳定性三板斧,我怎么用?

阿里妹导读&#xff1a;如何治理测试稳定性问题&#xff1f;很多人会说&#xff1a;环境、流程管控、监控、工具化、加机器、专人负责、等等。这些都是对的。不过这些都是解决方案层面的&#xff0c;而不是方法论和理论体系层面的。今天&#xff0c;阿里研究员郑子颖来说说测试…

HttpModule与HttpHandler详解

ASP.NET对请求处理的过程&#xff1a;当请求一个*.aspx文件的时候&#xff0c;这个请求会被inetinfo.exe进程截获&#xff0c;它判断文件的后缀&#xff08;aspx&#xff09;之后&#xff0c;将这个请求转交给 ASPNET_ISAPI.dll&#xff0c;ASPNET_ISAPI.dll会通过http管道&…

【iOS开发】---- 强大的UI修改工具 UIAppearance-有图片效果

iOS5及其以后提供了一个比较强大的工具UIAppearance&#xff0c;可以轻松的统一你的界面&#xff0c;它提供如下两个方法&#xff1a; (id)appearance (id)appearanceWhenContainedIn:(Class <>)ContainerClass,... 第一个方法是统一全部改&#xff0c;比如你设置UINav…

7月9日王者荣耀服务器维护,王者荣耀 7月9日体验服停机更新公告

亲爱的召唤师&#xff1a;为了增加版本的稳定性&#xff0c;我们计划在2021年7月9日16:00-17:00对《王者荣耀》体验服进行停机维护。【更新时间】7月9日16:00-17:00(15:30关闭PVP)【更新方式】停机更新【更新范围】王者荣耀修炼之地体验服【下载地址】体验服更新完毕后&#xf…

使用Jetty设置JNDI(嵌入式)

我在开发工作区上运行嵌入式Jetty&#xff0c;从而节省了一些编译和部署恶性循环的时间。 我与Jetty的合作不多&#xff0c;易用性使我着迷于它。 我需要设置JNDI才能检索与数据库相关的活动的连接池。 尽管某些地方有完整的文档&#xff0c;但大多数都是分散的。 因此&#xf…

交华为换机access配置_华为交换机Hybrid接口及基础配置

一、回顾VLANVLAN基本概念VLAN即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上划分成多个广播域(多个VLAN)的通信技术。VLAN内的主机间可以直接通信&#xff0c;而VLAN间不能直接互通&#xff0c;从而将广播报文限制在一个VLAN内。由于VLAN之间的隔离&#xff0c;所以一些类…

HttpClient使用之下载远程服务器中的文件(注意目录遍历漏洞)

参考文献&#xff1a; http://bbs.csdn.net/topics/390952011 http://blog.csdn.net/ljj_9/article/details/53306468 1.下载地址 http://hc.apache.org/downloads.cgi Apache-》Projects-》HttpComponents 2.DownloadServlet 1 package com.servlet;2 3 import java.io.Buffer…