有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java方法返回对象还是直接操作它?

我偶然发现了这段(对我来说很奇怪的)代码。事实上,我从来没有见过这个被使用过,我自己也从来没有使用过,所以这是一件非常令人困惑的事情。。。这与

  • 这里使用hashmap作为示例,但其他对象的行为也一样
public static void fillData(HashMap<Object, Object> dataMap){
    dataMap.put("key","value");
}

这让人很困惑,因为我知道你是这样做的

public static HashMap<Object, Object> fillData(){
    HashMap<Object, Object> dataMap = new HashMap<>();
    dataMap.put("key","value");
    return dataMap;
}

现在有没有一个时间我应该用一种或另一种方法?我对编程还是相当陌生,但是我还没有发现很多关于这种结构的东西

我也做过实验,发现这只适用于对象,而不适用于原语


共 (5) 个答案

  1. # 1 楼答案

    好吧,考虑一下这个方法操纵现有非空映射的情况。在这种情况下,第一个例子非常有意义

  2. # 2 楼答案

    我遵循的实践基于两种情况:

    情景1。如果调用方法对传递给方法的复杂对象进行了更改,那么修改传递的对象并从方法中不返回任何内容(void)就更有意义。在java中,对象是通过值传递的(这里的“值”指的是复制和传递的对象引用信息),因此任何修改都将更新对象的主副本,不需要从方法返回任何内容

    情景2。如果调用方法使用传递的复杂对象,运行一些逻辑并准备另一种类型的复杂对象,那么从方法中创建并返回这个新对象是有意义的

    回到你的问题- 这是一种静态方法,因此它与实例无关。我可以再次想到两种可能的情况:

    场景1——如果您的“dataMap”可以在这个方法调用之前启动,并且它可能已经有了一些其他的键值对,那么传递这个“dataMap”并让该方法用附加的键值对更新这个相同的映射就更简单了。在这种情况下,不会退还任何东西

    场景2——如果在这个方法调用之前,你的“dataMap”总是被认为是一个新的空映射,那么我看不出有任何理由创建map实例并在方法中传递它。如果该方法创建这个映射并作为方法返回参数返回,那么代码行会更少,也会更简单

    根据给定的场景,这两种方法都有其适用性,我不会说一种比另一种更好

  3. # 3 楼答案

    早上我在谷歌上搜索同一个主题,发现了 this discussion,上面说

    public static void fillData(HashMap<Object, Object> dataMap){
        dataMap.put("key","value");
    }
    

    被认为是“一个糟糕的实践,退化或预OOP时代”

  4. # 4 楼答案

    在java上,一种方法参数,它不是包含对象引用的原语。 以你为例

    public static void fillData(HashMap<Object, Object> dataMap){
        dataMap.put("key","value");
    }
    

    引用对象的dataMap以及对该对象的任何更改都会影响显示该对象的整个系统引用

    例如

    public static void fillAll(){
            HashMap<Object, Object> dataMap1 = new HashMap<>();
            HashMap<Object, Object> dataMap2 = dataMap;
            HashMap<Object, Object> dataMap3 = dataMap;
            //dataMap1, dataMap2, dataMap3 are same object's references.
            fillData1(dataMap1);
            fillData2(dataMap2);
            fillData3(dataMap3);
            //here dataMap1 holds 3 different values in it.
            //dataMap2, dataMap3 still same as dataMap1 
            dataMap3 = new HashMap<>();
            //here dataMap3 have a new object's reference but dataMap1 and dataMap2 still have 3 values in the map object.
            //primitive types are different they are holding values directly.
            int x = 5;
            int y = x;
            x++; //now x value is 6 but y value is still 5
    }
    
    public static void fillData1(HashMap<Object, Object> dataMap){
        dataMap.put("key1","value1");
    }
    
    public static void fillData2(HashMap<Object, Object> dataMap){
        dataMap.put("key2","value2");
    }
    
    public static void fillData3(HashMap<Object, Object> dataMap){
        dataMap.put("key3","value3");
    }
    
  5. # 5 楼答案

    让我们来看看这类API的用法(用HashMap替换为Map,使用接口而不是具体实现总是更好):

    Map<Object, Object> data = new Map<>();
    fillData(data);
    

    这样的传递参数会产生API中看不到的副作用代码。因此,更好地让方法返回结果,也可以通过这种方式变得更加流畅:

    Map<Object, Object> data = fillData(new HashMap<>());
    

    如果之前的地图中有“key”的值,会发生什么?它会被替换吗?通过返回原始地图的副本,该方法也可以避免副作用:

    public static Map<Object, Object> filledData(Map<Object, Object> original) {
        Map<Object, Object> result = new HashMap<>(original);
        result.put("key","value");
        return result;
    }
    

    功能方法独立于初始状态:

    Map<Object, Object> data = createFilledData();
    

    使用什么取决于需求,一如既往。这是公共API还是内部助手方法?谁会使用它,新手还是专家?表现如何