Java函数返回局部对象

结论: 在java函数里面创建局部对象,当返回这个对象时这个对象不会被销毁。

参考:https://blog.csdn.net/shkkhd/article/details/1829584
Class ObjectA{}

Public Class Test{
         Public static ObjectA  Factory(){
                  return new ObjectA();
        }
}
 上面例子中Test类中Factory方法返回一个局部的ObjectA对象,我就产生疑问,局部对象在方法外不是销毁了吗,这样返回是不是有问题.

这样写肯定是没有问题的,我查了资料,这样返回的是新ObjectA对象的Reference,就像对象的赋值操作一样,赋的是对象的Reference,而引用是个整型的,方法外值是不会变的.返回的新对象是由GC来回收的,只要有引用还指向这个对象,它就不会被回收.明显的,对象的引用在返回后还指向这个对象.所以,java中函数把一个局部对象作为返回值是可以的.
--------------------- 
作者:shkkhd 
来源:CSDN 
原文:https://blog.csdn.net/shkkhd/article/details/1829584 
版权声明:本文为博主原创文章,转载请附上博文链接!

先写一个测试用例.
PasswordItem类

public class PasswordItem {
    public int zjc_1;
    public int zjc_2;

    PasswordItem() {

    }

    public int getZjc_1() {
        return zjc_1;
    }

    public void setZjc_1(int zjc_1) {
        this.zjc_1 = zjc_1;
    }

    public int getZjc_2() {
        return zjc_2;
    }

    public void setZjc_2(int zjc_2) {
        this.zjc_2 = zjc_2;
    }
}


Main.class



import java.util.List;

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        System.out.println("Hello World!");
        PasswordItem passwordItem = returnLocalObj();
        int zjc_1 = passwordItem.getZjc_1();
        int zjc_2 = passwordItem.getZjc_2();

//        List<PasswordItem> zjc = zjc_func();
//        zjc.get(1).setZjc_1(100000);
        System.out.println("Hello World!");
    }

    private static PasswordItem returnLocalObj() {
        PasswordItem passwordItem = new PasswordItem();
        passwordItem.setZjc_1(100000);
        passwordItem.setZjc_2(123456);
        return passwordItem;
    }
}




在这里插入图片描述
在这里插入图片描述
从上面的调试结果看出从局部函数返回的passwordItem:PasswordItem@506 并未被销毁,而是被返回到了主函数的passwordItem对象里面。由此可见函数返回的对象不会被回收,我的理解是只要有指针指向这个对象的地址,就不会被java虚拟机回收这一点和c不一样,c语言里面在函数里面的局部参数在返回时会被销毁(除了new分配的堆空间)。而在java则是将其(准确的说函数返回对象的引用值)返回到了主函数。内存里面也会有一个PasswordItem空间。

还有一个有趣的事情。在写数据库的时候遇到的:
代码本意将数据库查询的条目返回到一个对象的数组里面。
代码如下:

PasswordItem passwordItem = new PasswordItem();
if (cursor.moveToFirst()) {
            do {
                passwordItem.setId(id);
                passwordItem.setAccount(cursor.getString(cursor.getColumnIndex("account")));
                /*-------------------------------------------*/
                //解密password
                /*-------------------------------------------*/
                ciperText = cursor.getString(cursor.getColumnIndex("password"));
                passwordItem.setPassword(encryption.decode(ciperText));
                passwordItem.setType(cursor.getInt(cursor.getColumnIndex("type")));
                passwordItem.setUri(cursor.getString(cursor.getColumnIndex("uri")));
                passwordItem.setNote(cursor.getString(cursor.getColumnIndex("note")));
                passwordItemList.add(passwordItem);
                id++;
            } while (cursor.moveToNext());
        }

其实上面的代码是个bug,原因在于这个函数只有一个PasswordItem对象,passwordItemList每次添加这个passwordItem是始终是添加的同一个引用值A。假设循环执行100次 password依次返回1…100 那么最后的结果是List里面存储了100个A,A指向同一块内存空间---->List由于全是同一块A,即是最后 List里面有100个相同的对象 结果List里面的元素的password全为100。下面的demo可以看到:

先随便写一个dmeo就可以测试到。

public class Main {

public static void main(String[] args) {
    System.out.println("Hello World!");
    List<PasswordItem> zjc = zjc_func();
    System.out.println("Hello World!");
}



public static List<PasswordItem> zjc_func() {
    List<PasswordItem> list = new ArrayList<PasswordItem>();
    PasswordItem passwordItem = new PasswordItem();
    passwordItem.setZjc_1(1);
    passwordItem.setZjc_2(2);
    list.add(passwordItem);
    passwordItem.setZjc_1(3);
    passwordItem.setZjc_2(4);
    list.add(passwordItem);
    return list;
}
}

在这里插入图片描述
上图看出 修改任意一个List元素 等价于修改全部




import java.util.Iterator;
import java.util.List;

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        System.out.println("Hello World!");
        List<PasswordItem> zjc = zjc_func();
        zjc.get(1).setZjc_1(100000);
        System.out.println("Hello World!");
    }



    public static List<PasswordItem> zjc_func() {
        List<PasswordItem> list = new ArrayList<PasswordItem>();
        PasswordItem passwordItem = new PasswordItem();
        passwordItem.setZjc_1(1);
        passwordItem.setZjc_2(2);
        list.add(passwordItem);
        passwordItem = new PasswordItem();
        passwordItem.setZjc_1(3);
        passwordItem.setZjc_2(4);
        list.add(passwordItem);
        return list;
    }
 }

在这里插入图片描述

在这里插入图片描述

if (cursor.moveToFirst()) {
            do {
                PasswordItem passwordItem = new PasswordItem();
                passwordItem.setId(id);
                passwordItem.setAccount(cursor.getString(cursor.getColumnIndex("account")));
                /*-------------------------------------------*/
                //解密password
                /*-------------------------------------------*/
                ciperText = cursor.getString(cursor.getColumnIndex("password"));
                passwordItem.setPassword(encryption.decode(ciperText));
                passwordItem.setType(cursor.getInt(cursor.getColumnIndex("type")));
                passwordItem.setUri(cursor.getString(cursor.getColumnIndex("uri")));
                passwordItem.setNote(cursor.getString(cursor.getColumnIndex("note")));
                passwordItemList.add(passwordItem);
                id++;
            } while (cursor.moveToNext());
        }

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值