java 定义final一个不可变的参数,将该参数绑定到另一个局部变量,然后改变该局部变量是否合法?[已关闭]

tpxzln5u  于 2023-02-20  发布在  Java
关注(0)|答案(3)|浏览(207)
    • 已关闭**。此问题为opinion-based。当前不接受答案。
    • 想要改进此问题吗?**请更新此问题,以便editing this post可以用事实和引文来回答。

8小时前关门了。
Improve this question
注意:同样的问题也适用于其他不可变类型,比如String和Boolean。
我有一个类似这样的方法(这是一个更复杂方法的简单示例):

示例1

public BigDecimal addTwo(BigDecimal bigDecimal) {
    bigDecimal = bigDecimal.add(new BigDecimal(2));
    return bigDecimal;
}

我知道,我可以简单地返回bigDecimal.add(new BigDecimal(2)),但这只是一个例子。
这段代码的问题是我不能将final添加到方法参数中,Eclipse让我很困扰。

示例2

public BigDecimal addTwo(final BigDecimal bigDecimal) {
    BigDecimal bigDecimalLocal = bigDecimal;
    bigDecimalLocal = bigDecimalLocal.add(new BigDecimal(2));
    return bigDecimalLocal;
}

我知道,我可以直接做BigDecimal bigDecimalLocal = bigDecimal.add(new BigDecimal(2))。但是我重复一遍,这只是一个例子。
问题是:当我这样做:

BigDecimal bigDecimalLocal = bigDecimal;

我***不是***创建一个新的BigDecimal。我是将相同的对象赋给不同的变量。我知道克隆BigDecimal的一个简单方法是:

示例3

BigDecimal bigDecimalLocal = new BigDecimal(bigDecimal.toString());

问题是:既然BigDecimal是不可变的,这真的有必要吗?我不能简单地像示例2那样做吗?我认为final关键字不能以这种方式无效。

toe95027

toe950271#

例2很好,但是你根本不需要局部变量,而且我认为它们会降低方法的可读性。

public BigDecimal addTwo(final BigDecimal bigDecimal) {
    return bigDecimal.add(BigDecimal.valueOf(2));
}

如果我想添加另一个BigDecimal”怎么办?我必须返回bigDecimal.add(BigDecimal.valueOf(2).add(BigDecimal.valueOf(3))?我认为它不是那么可读。
如果你要多次添加两个(或者多个常量),那么把常量提取为常量可能是有意义的。

private static final BigDecimal TWO = BigDecimal.valueOf(2);
private static final BigDecimal THREE = BigDecimal.valueOf(3);

public static BigDecimal addTwoAndThree(final BigDecimal bigDecimal) {
    return TWO.add(THREE).add(bigDecimal);
}
d4so4syb

d4so4syb2#

看来你不明白推荐人的概念。
当你有这个:

BigDecimal incoming = new BigDecimal(2);
addTwo(incoming);
...

public BigDecimal addTwo(BigDecimal bigDecimal) {
  bigDecimal = bigDecimal.add(new BigDecimal(2));
}

问题是:incoming在该方法结束后仍然是2!
add()调用创建了一个newBigDecimal对象,变量bigDecimal随后指向这个新对象。
但是引用incoming仍然指向旧对象!
长话短说:方法参数的关键字final,完全不是,你所想的,它唯一的目的是防止你重新赋值给那个参数,所以你真的想了解objects and references,和pass by reference之间的区别。

wsewodh2

wsewodh23#

好吧,我承认我对final关键字一无所知:

  • 当然,如果在方法中重新分配参数,不管是否为final,对象都保持不变
  • 如果改为修改一个非不可变对象,无论是否为final,该对象也会在方法外部更改。
  • 看起来final的参数唯一能做的就是不能只在方法中重新分配。

我得说我经常做这样的事:

public List<MyBean> findByNation(String nation) {
    if (nation != null) {
        nation = nation.toUpperCase();
    } else {
        nation = "";
    }
    
    [...]
}

public List<Date> findConfirmedDates(Date start, Date end) {
    if (end == null) {
        end = new Date();
    }
}

public String findFilteredSql(String queryFilter, SearchBean searchBean) {
    if (searchBean.getSupplierId() != null) {
        queryFilter += " JOIN SUPPLIER_COMMODITY sc ON sc.SUPPLIERID = v.SUPPLIERID ";
    }
    
    [...]
}

public static String format(BigDecimal val, Locale locale, int scale) {
    if (val == null) {
        return "-";
    }
    
    val = valLocal.subtract(BigDecimal.ONE);
    val = val.multiply(NumberUtility.BigDecimal100);
    
    [...]
}

恕我直言,我写上面的方法可读性更强,对不起final

相关问题