Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将java.lang.Number实例传递给方法时的final关键字_Java - Fatal编程技术网

将java.lang.Number实例传递给方法时的final关键字

将java.lang.Number实例传递给方法时的final关键字,java,Java,我在想,当传递java.lang.Number(例如java.lang.Long)的实例时,在方法签名中使用final关键字有什么意义 我认为这没有任何意义,因为java通过值传递对象尊重。这意味着java将原始引用的副本传递给该方法。此数字上的任何值更改在方法之外都是不可见的。因此,无论方法是否更改,方法内部的值都无关紧要 当然,当我们将pojo传递给一个方法时,使用final关键字是有意义的,但这是另一种情况 java.lang.Number演示版 public class Demo {

我在想,当传递java.lang.Number(例如java.lang.Long)的实例时,在方法签名中使用final关键字有什么意义

我认为这没有任何意义,因为java通过值传递对象尊重。这意味着java将原始引用的副本传递给该方法。此数字上的任何值更改在方法之外都是不可见的。因此,无论方法是否更改,方法内部的值都无关紧要

当然,当我们将pojo传递给一个方法时,使用final关键字是有意义的,但这是另一种情况

java.lang.Number演示版

public class Demo {

    public static void main(String[] args) {
        Long longValue = 1L;
        System.out.println("Long before: " + longValue);
        System.out.println(trickyMethod(longValue));
        System.out.println("Long after: " + longValue);

        BigInteger bigIntegerValue = BigInteger.ONE;
        System.out.println("BigInteger before: "+ bigIntegerValue);
        System.out.println(trickyMethod(bigIntegerValue));
        System.out.println("BigInteger after: " + bigIntegerValue);
    }

    private static String trickyMethod(Long value) {
        value = 10L;
        System.out.println("  trickyMethod: " + value);

        if (value.equals(10L))
            return "  equal";
        else
            return "  different";
    }

    private static String trickyMethod(BigInteger value) {
        value = BigInteger.TEN;
        System.out.println("  trickyMethod: " + value);

        if (value.equals(BigInteger.TEN))
            return "  equal";
        else
            return "  different";
    }
}
public class Demo {

    static class Container {
        private Long l;

        public Container(Long l) {
            this.l = l;
        }

        @Override
        public String toString() {
            return String.valueOf(l);
        }

        @Override
        public boolean equals(Object obj) {
            Container c = (Container) obj;
            return l.equals(c.l);
        }
    }

    public static void main(String[] args) {
        Container container = new Container(1L);
        System.out.println("Container before: "+ container);
        System.out.println(trickyMethod(container));
        System.out.println("Container after: " + container);
    }

    private static String trickyMethod(final Container container) {
        container.l = 10L;
        System.out.println("  trickyMethod: " + container);

        if (container.equals(new Container(10L)))
            return "  equal";
        else
            return "  different";
    }
}
和输出

Long before: 1
  trickyMethod: 10
  equal
Long after: 1

BigInteger before: 1
  trickyMethod: 10
  equal
BigInteger after: 1
Container before: 1
  trickyMethod: 10
  equal
Container after: 10
POJO演示

public class Demo {

    public static void main(String[] args) {
        Long longValue = 1L;
        System.out.println("Long before: " + longValue);
        System.out.println(trickyMethod(longValue));
        System.out.println("Long after: " + longValue);

        BigInteger bigIntegerValue = BigInteger.ONE;
        System.out.println("BigInteger before: "+ bigIntegerValue);
        System.out.println(trickyMethod(bigIntegerValue));
        System.out.println("BigInteger after: " + bigIntegerValue);
    }

    private static String trickyMethod(Long value) {
        value = 10L;
        System.out.println("  trickyMethod: " + value);

        if (value.equals(10L))
            return "  equal";
        else
            return "  different";
    }

    private static String trickyMethod(BigInteger value) {
        value = BigInteger.TEN;
        System.out.println("  trickyMethod: " + value);

        if (value.equals(BigInteger.TEN))
            return "  equal";
        else
            return "  different";
    }
}
public class Demo {

    static class Container {
        private Long l;

        public Container(Long l) {
            this.l = l;
        }

        @Override
        public String toString() {
            return String.valueOf(l);
        }

        @Override
        public boolean equals(Object obj) {
            Container c = (Container) obj;
            return l.equals(c.l);
        }
    }

    public static void main(String[] args) {
        Container container = new Container(1L);
        System.out.println("Container before: "+ container);
        System.out.println(trickyMethod(container));
        System.out.println("Container after: " + container);
    }

    private static String trickyMethod(final Container container) {
        container.l = 10L;
        System.out.println("  trickyMethod: " + container);

        if (container.equals(new Container(10L)))
            return "  equal";
        else
            return "  different";
    }
}
和输出

Long before: 1
  trickyMethod: 10
  equal
Long after: 1

BigInteger before: 1
  trickyMethod: 10
  equal
BigInteger after: 1
Container before: 1
  trickyMethod: 10
  equal
Container after: 10

Long
的情况下,为什么开发人员在方法签名中使用final关键字,比如
String方法(final Long value)

所有
java.lang
包包装类都是不可变的。这包括字符串、长字符、双字符等。因此,如果我们将它们标记为最终字符,这并不重要,这是正确的。但请记住,在您的示例中,您正在重新分配
引用。如果是说
StringBuilder
,那将是新的对象引用


但是您是对的,对于不可变的对象并不重要。

所有的
java.lang
包包装类都是不可变的。这包括字符串、长字符、双字符等。因此,如果我们将它们标记为最终字符,这并不重要,这是正确的。但请记住,在您的示例中,您正在重新分配
引用。如果是说
StringBuilder
,那将是新的对象引用


但是你是对的,在不可变对象的情况下并不重要。

开发人员使用以下内容的原因只是为了防止变量被重新分配

e、 g


因此,我想如果您不想在以后重新分配时意外地重新分配它,这将导致糟糕的情况,那么您可以将其声明为final。

开发人员使用以下命令的原因只是为了防止重新分配变量

e、 g


因此,我想如果您不想在以后重新分配时意外地重新分配它,将导致它出现糟糕的情况,那么您可以将其声明为final。

无论参数是否不变,这都无关紧要。最后一个可变参数可以在内部进行修改,但不能对参数变量重新赋值

Java中一个更无用的东西是,如果参数是隐式的final,那就更好了,因为如果您重新分配一个参数,这是一种代码味道。大多数代码分析器将其报告为错误/警告等


基本的经验法则是,除非语法上需要将参数
设置为final
(在非常罕见的情况下),否则不要在参数中设置final,因为它只会在代码中创建无用的混乱。但是,永远不要重新分配参数,因为它可能容易出现错误,并假装所有参数都是最终参数。

不管参数是否不变,这都无关紧要。最后一个可变参数可以在内部进行修改,但不能对参数变量重新赋值

Java中一个更无用的东西是,如果参数是隐式的final,那就更好了,因为如果您重新分配一个参数,这是一种代码味道。大多数代码分析器将其报告为错误/警告等


基本的经验法则是,除非语法上需要将参数
设置为final
(在非常罕见的情况下),否则不要在参数中设置final,因为它只会在代码中创建无用的混乱。但是,千万不要重新分配参数,因为它可能容易出现错误,并假装所有参数都是最终的。

重复使用变量和参数(语义发生了变化)通常是令人费解和难以发现的错误的来源。如果您试图给参数一个新值,则
final
关键字会给您一个编译器错误。此外,由于内部原因,当在该方法中创建的匿名类中使用该参数时,该参数必须是
final
。在
trickyMethod
中,您正在重新分配
container.l
,它不是final字段。如果您重新分配
容器
本身,则会出现编译器错误变量和参数的重用(语义已更改)通常是异常和难以发现的错误的来源。如果您试图给参数一个新值,则
final
关键字会给您一个编译器错误。此外,由于内部原因,当在该方法中创建的匿名类中使用该参数时,该参数必须是
final
。在
trickyMethod
中,您正在重新分配
container.l
,它不是final字段。如果重新分配
容器
本身,则应该会出现编译器错误“所有java.lang包包装类都是不可变的”。我们是否在方法参数上使用
final
与此无关。“所有java.lang包包装类都是不可变的。”无论我们是否在方法参数上使用
final
,都与此无关。在这种情况下不是。对不起,您能在此基础上展开吗?您所写的是真的;)但问题本身是关于擦肩而过。经过r.oh,好的,我明白了:),这是他的问题“为什么开发人员在方法签名中使用final关键字,比如在Long的情况下使用String方法(final Long value)”,我想我刚刚回答了这个问题OP在问这个问题,但我认为他有另一个问题。不是在这种情况下。对不起,你能详细说明一下吗?你写的是真的;)但问题本身是关于擦肩而过。经过r.oh,好的,我明白了:),这是他的问题“为什么开发人员在方法签名中使用final关键字,比如在Long的情况下使用String方法(final Long value)”,我想我刚刚回答了这个问题OP在问这个问题,但我认为他还有另一个问题。