Java编程语言中几种不同的引用类型是面试时经常容易被问到的问题:强引用,软引用,弱引用,虚引用。
其实除了Java之外,某些 其他编程语言也有类似概念,比如ABAP。今天我们就来比较一下。
根据ABAP帮助文档,我们可以把某个对象的引用包在一个Weak Reference的实例里。ABAP的Weak Reference实例通过类CL_ABAP_WEAK_REFERENCE实现。
看下面的例子:首先我在堆上创建了一个新的LCL_PERSON实例,然后包到一个ABAP weak reference里。
lo_person = NEW lcl_person( 'Jerry' ).
lo_weak = NEW cl_abap_weak_reference( lo_person ).
稍后,我们想拿到被包裹的lo_person引用时,使用weak reference提供的get方法。见下图示例:
lo_person = CAST lcl_person( lo_weak->get( ) ).
引用lo_person什么时候会变成initial呢?如果当ABAP垃圾回收器(Garbage Collector)开始工作时,已经没有任何引用再指向lo_person, 则lo_person会变成initial。
看下面这个例子加深理解。
REPORT ztest.
PARAMETERS: clear TYPE char1 as CHECKBOX DEFAULT abap_true,
gc TYPE char1 as CHECKBOX DEFAULT abap_true.
CLASS lcl_person DEFINITION.
PUBLIC SECTION.
DATA: mv_name TYPE string.
METHODS: constructor IMPORTING !iv_name TYPE string.
ENDCLASS.
CLASS lcl_person IMPLEMENTATION.
METHOD: constructor.
me->mv_name = iv_name.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA: lo_person TYPE REF TO lcl_person,
lo_weak TYPE REF TO cl_abap_weak_reference.
lo_person = NEW lcl_person( 'Jerry' ).
lo_weak = NEW cl_abap_weak_reference( lo_person ).
IF clear = abap_true.
CLEAR: lo_person.
ENDIF.
IF gc = abap_true.
cl_abap_memory_utilities=>do_garbage_collection( ).
ENDIF.
lo_person = CAST lcl_person( lo_weak->get( ) ).
IF lo_person IS INITIAL.
WRITE: / 'reference not available'.
ELSE.
WRITE: / 'reference still available'.
ENDIF.
这个report有两个开关,如下图。第一个开关控制lo_person这个引用是否被关键字CLEAR显式地置为INITIAL, 第二个开关决定是否在代码中显式地调用ABAP垃圾回收器。
这两个开关的打开和关闭状态,一共有4种组合。
在第一种情况下,通过关键字CLEAR清除了lo_person的引用,从ABAP的内存检查器(事务码s_memory_inspector)能发现,lo_person现在已经不指向任何内存中的对象了。
对于其他三种情况,LCL_PERSON的实例都不会被ABAP垃圾回收器清除:
Java
Java中的weak reference表现行为和ABAP一致。
我把上面的ABAP测试代码用Java程序重新写一遍:
import java.lang.ref.WeakReference;
class Person {
private String mName;
public Person(String name) {
this.mName = name;
}
public String getName() {
return this.mName;
}
}
public class WeakReferenceTest {
public static void check(Person person) {
if (person == null) {
System.out.println("Reference invalid");
}
else {
System.out.println("Reference still available");
}
}
public static void main(String[] args) {
Person jerry = null;
WeakReference<Person> person = new WeakReference<Person>(new Person(
"Jerry"));
jerry = new Person("Ben");
// if you comment out this line, Reference will be available
System.gc();
Person restore = person.get();
check(restore);
}
}
ABAP Soft reference - ABAP软应用
在我目前使用的ABAP Netweaver 750 SP4系统中,ABAP软应用尚未实现,
在系统里只有个空的CL_ABAP_SOFT_REFERENCE, 其描述信息写的是Do Not Use this Class!
那么我们就来试试Java的软应用 Soft Reference:
package reference;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
class Person2 {
private String mName;
public Person2(String name) {
this.mName = name;
}
public String getName() {
return this.mName;
}
public void finalize() {
System.out.println("finalize called: " + this.mName);
}
public String toString() {
return "Hello, I am " + this.mName;
}
}
public class SoftReferenceTest {
public static void main(String[] args) {
SoftReference<Person2> person = new SoftReference<Person2>(new Person2(
"Jerry"));
System.out.println(person.get());
ArrayList<Person2> big = new ArrayList<Person2>();
for (int i = 0; i < 10000; i++) {
big.add(new Person2(String.valueOf(i)));
}
System.gc();
System.out.println("End: " + person.get());
}
}
控制台打印出的输出:
Hello, I am Jerry
End: Hello, I am Jerry
即便我创建了1万个Person对象的实例,确实消耗了一些内存,然后内存消耗还远远没有大到会导致包含在软应用中的Person2类的引用被JDK删除掉的程度。因此我在代码中调用Java的垃圾回收器System.gc()之后,该引用仍然存在。
在Java中,软应用通常被用来实现在内存资源很有限的环境下的缓存机制,比如Android手机开发中。
Java 虚引用 PhantomReference
使用下面的代码测试虚引用:
package aop;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class PhantomReferenceTest {
public static void main(String[] args) {
Object phantomObj;
PhantomReference phantomRef, phantomRef2;
ReferenceQueue phantomQueue;
phantomObj = new String("Phantom Reference");
phantomQueue = new ReferenceQueue();
phantomRef = new PhantomReference(phantomObj, phantomQueue);
System.out.println("1 Phantom Reference:" + phantomRef.get());
System.out.println("2 Phantom Queued: " + phantomRef.isEnqueued());
phantomObj = null;
System.gc();
System.out.println("3 Anything in Queue? : " + phantomQueue.poll());
if (!phantomRef.isEnqueued()) {
System.out.println("4 Requestion finalization.");
System.runFinalization();
}
System.out.println("5 Anything in Queue?: " + phantomRef.isEnqueued());
phantomRef2 = (PhantomReference) phantomQueue.poll();
System.out.println("6 Original PhantomReference: " + phantomRef);
System.out.println("7 PhantomReference from Queue: " + phantomRef2);
}
}
测试输出:
1. Phantom Reference: null
2. Phantom Queued: false
3. Anything in Queue? : null
5. Anything in Queue?: true
6. Original PhantomReference: java.lang.ref.PhantomReference@2a139a55
7. PhantomReference from Queue: java.lang.ref.PhantomReference@2a139a55
和之前介绍的弱引用(WeakReference)和软引用(SoftReference)不同,包裹在虚引用(PhantomReference)中的对象实例无法通过需引用的get方法返回,因此在第一行输出我们会看到: “1. Phantom Reference: null”.
在上面示例代码中虚引用PhantomReference的构造函数里, 我传入了一个队列作为输入参数。当包裹在虚引用实例中的对象引用被Java垃圾回收器删除时,虚引用实例本身会自动被JVM插入我之前指定到虚引用构造函数输入参数的那个队列中去。
在System.runFinalization()执行之前,phantomRef.isEnqueued()返回false,phantomQueue.poll()返回空。
当phantomObj实例被JVM删除后, 虚引用PhantomReference本身被加入到队列中,并且能够通过队列提供的API所访问:phantomQueue.poll(). 打印输出的第6行和第7行也说明了这一点。
要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:
相关推荐
ABAP 程序的 8 种类型 ABAP 程序有哪些类型?在用事务码 SE38 创建新程序时,总是被要求指定一个程序类型,这些程序类型...ABAP 程序的 8 种类型各有其特点和用途,正确选择程序类型是创建成功的 ABAP 程序的关键。
在IT领域,尤其是在企业级应用开发中,Java和ABAP(Advanced Business Application Programming)是两种常用的编程语言。Java广泛应用于互联网应用,而ABAP则是SAP系统的核心编程语言。为了实现不同系统的集成和数据...
Java与SAP ABAP之间的通信主要通过Remote Function Call (RFC)接口实现,这是一种标准化的方式,允许不同系统间的双向数据交换。在本项目中,我们使用了JCo3(Java Connector version 3)库,它是SAP提供的Java API...
【SAP ABAP调用Java生成的Web Service手册】 在SAP系统中,与外部服务进行...通过以上步骤,你可以在SAP ABAP环境中成功调用由Java生成的Web Service。这不仅扩展了SAP的功能,也实现了不同系统间的集成和数据交换。
通过配置JCo服务器程序以及编写相应的ABAP和JAVA代码,可以实现跨系统的数据传输和处理功能。这对于集成不同技术平台的应用系统来说是非常重要的技术手段之一。此外,本案例还强调了在开发过程中需要注意的一些细节...
ABAP(Advanced Business Application Programming)是SAP公司开发的一种编程语言,主要用于开发SAP系统中的业务应用程序。这个“ABAP中文帮助文档”包含了对ABAP基础、报表编写以及事务处理的详细指南,对于学习和...
在ABAP中,对BOM进行按层展开是为了更好地管理和分析产品的生产过程。 在描述中提到的博文链接,虽然无法直接访问,但通常博主会分享如何在ABAP编程中实现BOM的层次遍历和展示。这可能包括以下几种方法: 1. **...
- ABAP/4支持多种数据类型,包括基本数据类型(如字符、数值)和复合数据类型(如内表)。 **2. 将数据输出到屏幕** - **输出数据**:使用`WRITE`等命令将数据输出到屏幕或列表。 - 支持格式化输出,如添加标题、...
在进行计算时,ABAP的F(Floating Point)类型可能会因为浮点数的精度问题导致不精确的结果,如示例中的`f3 = f1 - f2`,而P类型则可以避免这种精度问题,提供精确的计算结果。因此,当需要进行高精度计算时,P类型...
此外,文本元素的处理也是ABAP编程中的重要组成部分,涉及创建、更改、选择文本元素,以及翻译和比较文本符号的方法。 #### 数据处理与转换 数据处理包括赋值、数值运算、字符串操作和类型转换等。手册详细阐述了...
为了提高ABAP/4程序的性能,文档还提到了运行时间分析(通过事务SE30或SE38中的“运行时间分析”)和一些最佳实践,帮助开发者优化代码,提升系统效率。 文档中还包含了对SAP联机帮助的一般约定,如屏幕文本、用户...
- 想了解如何优化ABAP/4任务性能,可从“ABAP/4开发工作台”选择事务SE30或“测试->运行时间分析”,随后点击“提示和技巧”。 #### 五、ABAP/4的书写约定与语法规则 - 屏幕文本、用户输入、可变用户输入、报表名...
了解和熟练掌握ABAP对象类型对于任何在SAP环境中工作的开发人员都是至关重要的,它能帮助他们更有效地组织和维护代码,确保系统的稳定性和可维护性。同时,正确使用对象类型也有助于团队协作,因为它们定义了清晰的...
为了提高ABAP/4任务的性能,用户可以从“ABAP/4开发工作台”选择事务SE30或“测试->运行时间分析”,并点击“提示和技巧”。 #### 五、SAP在线帮助约定与语法约定 SAP在线帮助中采用了特定的约定来区分屏幕文本、...
ABAP是一种结构化的编程语言,它包含了一系列基本数据类型(如I, N, C等)和变量声明。在ABAP中,程序由若干个块组成,包括报告、形式(FORM)、函数模块等。报告是ABAP程序的入口点,用于定义程序的整体逻辑;形式...
- 内部表:用于存储多行数据,可以动态增长,有标准和透明两种类型。 - 表类型:定义内部表的结构,用于声明和定义内部表。 7. **ABAP动态编程** - 动态SQL:允许在运行时生成和执行SQL语句,提高了灵活性。 - ...
ABAP,全称为Advanced Business Application Programming,是一种高级业务应用编程语言,主要被用于SAP(System Applications and Products in Data Processing)系统中进行企业级应用程序的开发。本教程以"30天学会...
ABAP是一种结构化编程语言,主要用于SAP R/3系统和SAP NetWeaver平台。它支持事务处理、报表生成、用户接口设计以及与其他系统集成等多种功能。ABAP与SAP的业务逻辑紧密相连,是构建SAP解决方案的重要工具。 二、...
ABAP REPORT程序是SAP开发中最常见的程序类型之一,通过定义数据结构、查询条件以及处理逻辑,可以实现对SAP系统中数据的有效提取和展示。通过对上述示例的学习,开发者可以更好地理解ABAP REPORT程序的设计思路和...
Table Type 是 ABAP 中的一种特殊的内表,它是通过定义一个表类型来存储数据的。Table Type 的优点是可以根据需要定义表结构,并且可以存储大量数据。然而,Table Type 的缺点是需要手动定义表结构,并且需要更多的...