Java中同名对象是否会被覆盖?同名对象创建规则相关问题咨询
Java同名对象声明相关问题解答
首先明确核心概念:Java中的变量名只是指向堆内存中对象的引用,并非对象本身。所谓「使用相同名称声明对象」本质是更换当前引用指向的对象,原有对象如果没有其他引用关联,就会被垃圾回收器自动回收。
示例1问题解答
你给出的循环代码中,testObject是循环体内的局部变量,作用域仅限单次循环迭代:
for (int x = 0; x < 500000000; x++) { TestObject testObject = new TestObject(); }
- 每次迭代都会创建一个新的
TestObject实例,同时生成一个新的局部引用testObject指向这个新实例 - 单次迭代结束后,当前的
testObject引用就会销毁,对应实例如果没有其他引用关联,就会被垃圾回收器标记回收 - 最终不会积累5亿个实例占用内存,也不是始终只保留1个实例:同一时间存活的实例通常只有当前迭代的1个,之前的实例会被GC自动清理。
示例2写法对比解答
如果你的需求是每次点击时不重复创建新的List对象,首先要明确:你给出的两种写法都会触发新List实例的创建,因为两种写法都调用了getRunningService(),如果该方法返回的是新生成的List对象,那么两种写法都会创建新实例。两种写法的对比如下:
第一种写法的问题
//Using this way? List < ActivityManager.RunningServiceInfo > runningServiceInfoList = getRunningService(); activityMainBinding.activityMainConstraintLayout19.setOnClickListener(v -> { runningServiceInfoList.clear(); runningServiceInfoList = getRunningService(); if (...) });
- 代码冗余:
runningServiceInfoList.clear()是完全无用的操作,下一行直接把引用指向了新返回的List实例,清空原列表的操作没有任何意义 - 有内存泄漏风险:外部持有List引用,被点击回调的闭包捕获后,可能会延长对象的生命周期,带来不必要的内存占用风险。
第二种写法的优势
//Or this way? activityMainBinding.activityMainConstraintLayout19.setOnClickListener(v -> { List < ActivityManager.RunningServiceInfo > runningServiceInfoList = getRunningService(); if (...) });
runningServiceInfoList是回调内部的局部变量,作用域仅限单次点击回调的执行周期,回调执行结束后引用就会销毁,对应List实例会被GC自动回收,没有额外的内存泄漏风险- 没有冗余操作,代码更简洁易读。
真正满足「不重复创建新对象」的最优写法
如果要做到每次点击都不创建新的List实例,只复用同一个对象,应该这么写:
// 仅初始化一次List实例 List<ActivityManager.RunningServiceInfo> runningServiceInfoList = new ArrayList<>(); activityMainBinding.activityMainConstraintLayout19.setOnClickListener(v -> { // 复用已有实例,清空旧数据后填充新数据,不创建新的List对象 runningServiceInfoList.clear(); runningServiceInfoList.addAll(getRunningService()); if (...) });
内容的提问来源于stack exchange,提问作者Taha Sami
相关产品推荐
相关产品推荐

