发布(Publish)一个对象是指使对象能够在当前作用域之外的代码中被使用。例如将指向该对象的引用保存到其他代码可以访问到的地方 ,或者在一个非私有的方法中返回一个对象的引用或者将该引用传递到其他类的方法中。当发布一个对象时,在该对象的非私有域中的引用同样被发布出去,一般来说如果一个已经发布的对象能够通过非私有的变量和方法调用到其他的对象那么这个对象也被发布。
逸出(Escape)是指 一个比应该被发布的对象被发布出去。
在 《Java Concurrency in Practice》中关于隐式使用This 引用逸出的示例,比较难以理解如何逸出。ThisEscape发布EventListener时,也隐含地发布了ThisEscape实例本身,因为在这个内部类的实例中包含了对ThisEscape 实例的隐含引用。这个个人的理解代码是:
/** * * @author zhangwei_david * @version $Id: ThisEscape.java, v 0.1 2014年11月3日 上午9:37:54 zhangwei_david Exp $ */ public class ThisEscape { private String name = null; public ThisEscape(EventSource source) { source.registerListener(new EventListener() { public void onEvent(Event event) { doSomething(event); } }); name = "TEST"; } /** * * @param event */ protected void doSomething(Event event) { System.out.println(name.toString()); } } import java.awt.Event; /** * * @author zhangwei_david * @version $Id: Listener.java, v 0.1 2014年11月3日 上午9:40:13 zhangwei_david Exp $ */ public interface EventListener { public void onEvent(Event event); }
/** * * @author zhangwei_david * @version $Id: EventSource.java, v 0.1 2014年11月3日 上午9:38:40 zhangwei_david Exp $ */ public class EventSource { public void registerListener(EventListener listener) { listener.onEvent(null); } }
/** * * @author zhangwei_david * @version $Id: Client.java, v 0.1 2014年11月3日 上午9:45:48 zhangwei_david Exp $ */ public class Client { /** * * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { EventSource es = new EventSource(); new ThisEscape(es); } }
运行的结果是:
Exception in thread "main" java.lang.NullPointerException at com.cathy.demo.concurrency.escape.ThisEscape.doSomething(ThisEscape.java:33) at com.cathy.demo.concurrency.escape.ThisEscape$1.onEvent(ThisEscape.java:21) at com.cathy.demo.concurrency.escape.EventSource.registerListener(EventSource.java:15) at com.cathy.demo.concurrency.escape.ThisEscape.<init>(ThisEscape.java:18) at com.cathy.demo.concurrency.escape.Client.main(Client.java:21)
这个就是由于在name 初始化之前,就使用了ThisEscape实例,而此时实例尚未完成初始化。
同样修改SafeListener
import java.awt.Event; /** * * @author zhangwei_david * @version $Id: SafeListener.java, v 0.1 2014年11月3日 上午10:20:26 zhangwei_david Exp $ */ public class SafeListener { private final EventListener listener; private String name = null; private SafeListener() { listener = new EventListener() { public void onEvent(Event event) { doSomething(); } }; name = "TEST"; } public static SafeListener newInstance(EventSource eventSource) { SafeListener safeListener = new SafeListener(); eventSource.registerListener(safeListener.listener); return safeListener; } /** * */ protected void doSomething() { System.out.println(name.toString()); } } /** * * @author zhangwei_david * @version $Id: Client.java, v 0.1 2014年11月3日 上午9:45:48 zhangwei_david Exp $ */ public class Client { /** * * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { EventSource es = new EventSource(); // new ThisEscape(es); SafeListener.newInstance(es); } }
结果是:
TEST
相关推荐
这些隐式对象无需显式声明即可直接使用。 ##### 1. 与范围相关的隐式对象 - **pageScope**: 表示当前页面的作用域。 - **requestScope**: 表示当前HTTP请求的作用域。 - **sessionScope**: 表示当前用户的会话作用...
标题中的"matlab.rar_matlab隐式_一维热方程_热传导 matlab_热传导 隐式_隐式差分"表明这是一个关于使用MATLAB解决一维热传导方程的实例,其中采用了隐式差分方法。一维热传导方程是描述物体内部热量传递的经典数学...
例如,如果我们有一个名为`test.dll`的DLL,其中包含一个名为`MyFunction`的函数,使用隐式链接时,我们需要以下步骤: 1. **头文件声明**:在项目中包含`test.h`头文件,该头文件声明了`MyFunction`的原型。 ```...
本教程主要探讨显式Intent和隐式Intent以及Intent Filter的使用,旨在帮助开发者更好地理解和应用这些概念。 首先,让我们理解显式Intent。显式Intent是一种明确指定接收方的Intent。在创建显式Intent时,我们需要...
本资源"implicitQR_matlab_数值线性代数_隐式QR"提供了一种使用MATLAB实现的隐式QR算法,特别是双重步位移的QR迭代算法。 首先,我们来理解一下隐式QR(Implicit QR)算法。传统的QR分解是通过Householder反射或...
另一方面,如果通过函数引用(alias)来调用方法,`this`的隐式绑定可能会丢失: ```javascript function foo() { console.log(this.a); } var obj = { a: 2, foo: foo }; var bar = obj.foo; var a = "oops, ...
标题中的“KWIC隐式调用风格实现”指的是在软件设计中采用的一种特定的编程模式。KWIC(Keyword-In-Context)通常用于文本处理,它将一个关键词在文本中的出现情况展示出来,使得关键词周围的上下文清晰可见。在这个...
例如,如果定义了`USE_IMPLICIT`,则使用隐式调用;否则,使用显式调用。这样,只需更改一个宏定义,就可以在同一个解决方案中轻松切换调用方式。 总结来说,隐式调用简化了代码,但更依赖于DLL的静态配置;而显式...
隐式调用DLL(Dynamic Link Library)是在Windows操作系统中一种常见的程序设计技术,它允许不同程序之间共享代码和数据。DLL文件本质上是可执行代码的集合,这些代码可以在多个应用程序中使用,从而节省内存和磁盘...
显示求解器使用显式积分方法,能够处理高度非线性问题,但时间步长受到稳定性条件的限制,通常会比较小,因此计算耗时较长。隐式求解器则采用隐式积分方法,可以通过调整载荷和时间步长,进行精确控制,适合于求解...
3. **用户选择**:如果有多于一个应用能处理隐式意图,系统会弹出让用户选择的对话框。为了避免这种情况,可以使用PackageManager的resolveActivity()方法检查是否有唯一的匹配项。 4. **测试**:测试隐式意图时,...
本篇将深入探讨如何使用隐式Intent在Android中打开一个新的Activity。 **隐式Intent** 的主要特点是不直接指定目标Activity的Class名称,而是通过定义Intent的Action、Data、Category等元数据来匹配系统中注册的...
根据给定的内容,我们可以梳理出关于C++中this指针的几个知识点,其中包括this指针的作用、使用场景以及与静态成员函数的关系。 首先,this指针是一个隐含在每个非静态成员函数中的特殊指针,它指向调用该成员函数...
下面我们将深入探讨隐式意图的工作原理以及如何使用它们来调用安卓系统的各种功能。 首先,理解隐式意图的基本结构。一个隐式意图通常包含以下几部分: 1. **Action**:这是意图的主要行为,如ACTION_VIEW、ACTION...
隐式启动可能会暴露应用的部分功能,因此在处理敏感操作时需谨慎使用。 在实际开发中,开发者应根据需求选择合适的启动方式。对于同应用内部的简单跳转,显式启动更为合适;而对于需要调用系统服务或第三方应用的...
隐式面生成是三维计算机图形学领域中的一个重要概念,主要用于从一组离散的点云数据中重建出连续的表面模型。这种方法在逆向工程、医学成像、虚拟现实等领域有着广泛的应用。通过将点云转换为具有明确几何形状的表面...
### C语言隐式类型转换规则详解 ...然而,过度依赖隐式类型转换可能会导致意料之外的结果,因此理解并正确使用隐式类型转换规则是非常关键的。在编写代码时,合理利用显式类型转换也可以提高程序的效率和可读性。
本文将重点讨论隐式加载,并提供一个使用`SetDllDirectory`函数改变隐式加载DLL路径的实例代码。 **隐式加载(Load-Time Dynamic Linking)** 隐式加载是在编译和链接阶段进行的。当一个应用程序被编译和链接时,...