Java对象引用四种类型的使用

在 Java 中,对象引用分为四种类型:强引用(Strong Reference)软引用(Soft Reference)弱引用(Weak Reference)虚引用(Phantom Reference)。它们的主要区别在于对象的垃圾回收行为生命周期的不同。

1. 强引用 (Strong Reference)

定义

  • 普通的对象引用。
  • 只要有强引用指向一个对象,该对象就不会被垃圾回收。

1. 强引用 (Strong Reference)

定义

  • 普通的对象引用。
  • 只要有强引用指向一个对象,该对象就不会被垃圾回收

场景

  • 普通的业务对象
  • 假设我们正在处理用户的购物车,购物车对象应该始终存在于内存中,直到明确不需要它。

示例

public class ShoppingCart {
    private List<String> items;

    public ShoppingCart() {
        items = new ArrayList<>();
    }

    public void addItem(String item) {
        items.add(item);
    }

    public List<String> getItems() {
        return items;
    }

    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart(); // 强引用
        cart.addItem("Laptop");
        cart.addItem("Mouse");
        System.out.println(cart.getItems()); // 方法执行完之前不会被垃圾回收
    }
}

特点

  • 最常见的引用类型。
  • 即使内存不足,垃圾回收器也不会回收强引用指向的对象,可能导致 OutOfMemoryError

2. 软引用 (Soft Reference)

定义

  • 在内存不足时,垃圾回收器会回收软引用指向的对象。
  • 适合实现缓存机制。

场景

  • 图片缓存
  • 在内存充足时,图片缓存不会被清理;当内存不足时,优先清理缓存,释放内存。

示例

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;

public class ImageCache {
    private final Map<String, SoftReference<byte[]>> imageCache = new HashMap<>();

    public void putImage(String key, byte[] imageData) {
        imageCache.put(key, new SoftReference<>(imageData));
    }

    public byte[] getImage(String key) {
        SoftReference<byte[]> ref = imageCache.get(key);
        return ref != null ? ref.get() : null; // 如果缓存被回收,返回 null
    }

    public static void main(String[] args) {
        ImageCache cache = new ImageCache();
        byte[] largeImage = new byte[10 * 1024 * 1024]; // 10MB 图片
        cache.putImage("image1", largeImage);

        System.out.println("Image loaded: " + (cache.getImage("image1") != null));
        System.gc(); // 手动触发垃圾回收
        System.out.println("After GC, Image loaded: " + (cache.getImage("image1") != null));
    }
}

特点

  • 在内存充足时,软引用的对象不会被回收。
  • 当内存不足时,垃圾回收器会清理软引用,释放内存。
  • 适合用于缓存较大的对象(如图片、结果集)。

3. 弱引用 (Weak Reference)

定义

  • 无论内存是否充足,只要垃圾回收器运行,就会回收弱引用指向的对象。
  • 常用于 WeakHashMap 等数据结构。

场景

  • 弱引用映射(WeakHashMap)
  • 用于存储临时数据,比如存储和用户会话相关的配置信息。如果用户会话结束(强引用消失),数据会自动从映射中清除,避免内存泄漏。

示例

import java.util.Map;
import java.util.WeakHashMap;

public class WeakReferenceExample {
    public static void main(String[] args) {
        Map<Object, String> sessionData = new WeakHashMap<>();
        Object sessionKey = new Object(); // 使用弱引用作为键
        sessionData.put(sessionKey, "User Preferences");

        System.out.println("Before GC: " + sessionData);
        sessionKey = null; // 去除强引用
        System.gc(); // 手动触发垃圾回收
        System.out.println("After GC: " + sessionData); // 数据被清理
    }
}

特点

  • 即使对象正在使用,只要没有强引用或软引用指向它,也可能会被回收。
  • 适合用来管理无需长时间存活的对象。

4. 虚引用 (Phantom Reference)

定义

  • 不能通过虚引用获取对象。
  • 用于跟踪对象的垃圾回收状态。

场景

  • 监控对象的回收
  • 用于清理资源(如文件、数据库连接)。在对象即将被垃圾回收时,通过 ReferenceQueue 获取通知,并执行清理操作。

示例

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

public class PhantomReferenceExample {
    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<Object> refQueue = new ReferenceQueue<>();
        Object resource = new Object(); // 需要监控的资源
        PhantomReference<Object> phantomRef = new PhantomReference<>(resource, refQueue);

        System.out.println("Before GC: " + phantomRef.isEnqueued());
        resource = null; // 去除强引用
        System.gc(); // 手动触发垃圾回收

        // 等待资源被回收
        Thread.sleep(100);
        System.out.println("After GC: " + phantomRef.isEnqueued()); // 是否已加入队列
        if (refQueue.poll() != null) {
            System.out.println("Resource is ready for cleanup!");
            // 执行资源清理逻辑,例如关闭文件、断开数据库连接等。
        }
    }
}

特点

  • 必须与 ReferenceQueue 一起使用。
  • 虚引用的主要作用是对象被垃圾回收前进行一些清理工作(如资源释放)。
  • 虚引用的 get() 方法永远返回 null

对比总结

引用类型描述是否被回收的条件适用场景
强引用普通对象引用,默认引用类型永远不会被回收核心逻辑和对象的正常使用。
软引用在内存不足时可回收的引用内存不足时回收缓存对象。
弱引用弱化的引用,随时可能被回收GC 扫描到时回收临时性对象或映射。
虚引用不存活的引用,用于跟踪对象回收对象即将被回收时回收,并在 ReferenceQueue 中通知资源释放或清理。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值