“是否明智?”;剥削“;java按值调用

“是否明智?”;剥削“;java按值调用,java,methods,pass-by-reference,Java,Methods,Pass By Reference,考虑以下假设。用户可以输入以下内容 30天、90天、180天、360天、1米、3米、6米、12米、1年 (D=天,M=月,Y=年) 我想用以下两种方法计算月数 private int getLengthOfPeriodInMonths(Integer lengthOfPeriod, String unitOfPeriod) { int periodInMonths = lengthOfPeriod; if ("D".equals(unitOfPeriod)

考虑以下假设。用户可以输入以下内容 30天、90天、180天、360天、1米、3米、6米、12米、1年 (D=天,M=月,Y=年)

我想用以下两种方法计算月数

    private int getLengthOfPeriodInMonths(Integer lengthOfPeriod, String unitOfPeriod) {
        int periodInMonths = lengthOfPeriod;
        if ("D".equals(unitOfPeriod)) {
            periodInMonths = lengthOfPeriod / 30;
        } else if ("Y".equals(unitOfPeriod)) {
            periodInMonths = lengthOfPeriod * 12;
        }
        return periodInMonths;
    }

    private int getLengthOfPeriodInMonths(Integer lengthOfPeriod, String unitOfPeriod) {
        if ("D".equals(unitOfPeriod)) {
            lengthOfPeriod = lengthOfPeriod / 30;
        } else if ("Y".equals(unitOfPeriod)) {
            lengthOfPeriod = lengthOfPeriod * 12;
        }
        return lengthOfPeriod;
    }
因为java使用以值
lengthOfPeriod
形式传递的引用的值调用,所以在方法之外不会更改。我不知道用什么更合适


我知道这个方法可以通过使用enum
Periods
或类似的东西来重构。但是我们不要在这里讨论这个问题。

唯一的区别是您使用了自己的变量
int periodInMonths=lengthOfPeriod。但这不是必须的

你可以用第二个。。它做它应该做的

int lengthOfPeriodInMonths = getLengthOfPeriodInMonths(lengthOfPeriod, unitOfPeriod);
您将计算出的整数存储在
lengthOfPeriodInMonths

附言:这个电话

lengthOfPeriod = lengthOfPeriod / 30;
相当于

lengthOfPeriod = new Integer(lengthOfPeriod / 30);
(查看Java中的“自动装箱”)


所以,正如您所说,Java使用调用间隔值。变量
lengthOfPeriod
在此调用中被分配一个新的referenece。因此,此计算将在方法之外丢失!这就是为什么必须返回新计算的值

唯一的区别是使用自己的变量
int periodInMonths=lengthOfPeriod。但这不是必须的

你可以用第二个。。它做它应该做的

int lengthOfPeriodInMonths = getLengthOfPeriodInMonths(lengthOfPeriod, unitOfPeriod);
您将计算出的整数存储在
lengthOfPeriodInMonths

附言:这个电话

lengthOfPeriod = lengthOfPeriod / 30;
相当于

lengthOfPeriod = new Integer(lengthOfPeriod / 30);
(查看Java中的“自动装箱”)


所以,正如您所说,Java使用调用间隔值。变量
lengthOfPeriod
在此调用中被分配一个新的referenece。因此,此计算将在方法之外丢失!这就是为什么必须返回新计算的值

分配给方法参数不是一个好主意(默认情况下,它们应该是最终的IMHO)。如果您真的想避免额外的变量(并不是说它真的有什么不同),那么可以在If子句中添加返回


但不要将参数用作“自动局部变量”。它可能会导致难以看到的bug,并且不会使您的代码更具性能。

为方法参数赋值不是一个好主意(默认情况下,它们应该是最终的IMHO)。如果您真的想避免额外的变量(并不是说它真的有什么不同),那么可以在If子句中添加返回


但不要将参数用作“自动局部变量”。它可能会导致难以看到的错误,并且不会使您的代码更具性能。

第一条建议:永远不要修改方法参数。它们应始终反映方法用户传递的值

第二条建议:如果有人建议你永远不要做某事,特别是如果他或她用了“永远不要”这个短语,请对他的建议持保留态度。没有规则没有例外(从来没有;-)。这些规则都是很好的经验法则,但一定要用你自己的判断。选择你认为更清晰的解决方案。我知道在某些情况下,我发现修改方法参数比替代方法更具可读性

例如,有时您可能希望允许该方法的用户将
null
传递给该方法,但随后将其替换为某个默认值。我发现以下方法

public void doSomething(String s) {
    if (s == null) s = "";
    System.out.println(s);
}
比引入局部变量仅包含默认值更清楚:

public void doSomething(final String s) {
    String sOrEmpty = s == null ? "" : s;
    System.out.println(sOrEmpty);
}

第一条建议:永远不要修改方法参数。它们应始终反映方法用户传递的值

第二条建议:如果有人建议你永远不要做某事,特别是如果他或她用了“永远不要”这个短语,请对他的建议持保留态度。没有规则没有例外(从来没有;-)。这些规则都是很好的经验法则,但一定要用你自己的判断。选择你认为更清晰的解决方案。我知道在某些情况下,我发现修改方法参数比替代方法更具可读性

例如,有时您可能希望允许该方法的用户将
null
传递给该方法,但随后将其替换为某个默认值。我发现以下方法

public void doSomething(String s) {
    if (s == null) s = "";
    System.out.println(s);
}
比引入局部变量仅包含默认值更清楚:

public void doSomething(final String s) {
    String sOrEmpty = s == null ? "" : s;
    System.out.println(sOrEmpty);
}

你能解释一下这里应该发生什么吗?做任何让你的代码更清晰的事情。对我来说,它们都很好。我认为可能有一个普遍的问题:程序员可能会在第二个方法中更改lengthOfPeriod(通过setter),这可能会在该方法之外更改代码。请不要使用这两个方法,直接返回值:
if
中返回lengthOfPeriod/30
中的
返回长度周期*12
返回长度周期块外。@Tom我认为在一个方法中减少返回语句的数量几乎总是更清楚的。这里有一个条款:“一个方法应该总是有一个退出点”。你能解释一下这里应该发生什么吗?做任何让你的代码更清晰的事情。对我来说,它们都很好。我认为可能有一个普遍的问题:程序员可能会在第二个方法中更改lengthOfPeriod(通过setter),这可能会在该方法之外更改代码。请不要使用这两个方法,直接返回值:
if
中返回lengthOfPeriod/30
中的
返回长度周期*12
返回长度周期块外。@Tom我认为在一个方法中减少返回语句的数量几乎总是更清楚的。这里有一句话:“一个方法应该总是有一个退出点”。这正是我所知道的,但是放弃使用局部变量是否明智呢?是的,因为程序的执行速度快了一点,并且节省了工作内存等等;)还有:为什么要添加一些内容