Java函数返回局部对象

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

参考:https://blog.youkuaiyun.com/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 
来源:优快云 
原文:https://blog.youkuaiyun.com/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());
        }

Java中,函数(也称为方法)通常不允许直接返回多个值。因为Java的设计原理是基于单返回值的概念,每个方法只能通过一种方式返回数据,通常是通过一个`return`语句返回一个单一的数据类型。但是,可以采用几种间接的方式来处理需要同时返回多个值的情况: 1. 使用数组或集合:你可以创建一个包含多个元素的数组或列表作为返回值。例如,如果需要返回两个整数,可以创建一个`int[]`数组。 ```java public int[] getMultipleValues() { return new int[]{value1, value2}; } ``` 2. 使用自定义对象:创建一个包含多个属性的对象返回,这样可以在对象内部表示一组相关的值。 ```java public class ValuePair { private int value1; private int value2; public ValuePair(int value1, int value2) { this.value1 = value1; this.value2 = value2; } // 提供getter方法获取值 public int getValue1() { return value1; } public int getValue2() { return value2; } } public ValuePair getMultipleValues() { return new ValuePair(value1, value2); } ``` 3. 使用包装类:如`Pair`类或者第三方库提供的类似结构。 4. 变量引用:在方法体内声明局部变量,然后让接收者通过外部作用域访问这些变量。 尽管以上方法可以提供类似的效果,但它们都不是语言原生支持返回多个值的方式。在设计上,Java更倾向于使用结构化数据和方法组合来达到类似目的。如果你有特定的需求,可以考虑重构代码或者使用其他数据结构来代替。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值