如果我使用包装类而不是本地类的最终变量,这是错误的

时间:2014-02-04 07:06:46

标签: java

我正在尝试理解本地课程的概念。最终变量。我有来自java docs的代码。据我所知,本地类只能从其封闭块中获取最终变量。在下面的代码中,如果我声明 final int numberLength = 10; ,那就好了,但是再次包装类是不可变的&最后。所以,如果我将其声明为整数numberLength = new Integer(7);

public class LocalClassExample {

static String regularExpression = "[^0-9]";

public static void validatePhoneNumber(
    String phoneNumber1, String phoneNumber2) {

   // final int numberLength = 10;
    Integer numberLength=new Integer(7);
    // Valid in JDK 8 and later:

    // int numberLength = 10;

    class PhoneNumber {

        String formattedPhoneNumber = null;

        PhoneNumber(String phoneNumber){
            // numberLength = 7;
            String currentNumber = phoneNumber.replaceAll(
              regularExpression, "");
            if (currentNumber.length() == numberLength)
                formattedPhoneNumber = currentNumber;
            else
                formattedPhoneNumber = null;
        }

        public String getNumber() {
            return formattedPhoneNumber;
        }

        // Valid in JDK 8 and later:

 //            public void printOriginalNumbers() {
//                System.out.println("Original nubmers are " + phoneNumber1 +
//                    " and " + phoneNumber2);
//            }
    }

    PhoneNumber myNumber1 = new PhoneNumber(phoneNumber1);
    PhoneNumber myNumber2 = new PhoneNumber(phoneNumber2);

    // Valid in JDK 8 and later:

//        myNumber1.printOriginalNumbers();

    if (myNumber1.getNumber() == null) 
        System.out.println("First number is invalid");
    else
        System.out.println("First number is " + myNumber1.getNumber());
    if (myNumber2.getNumber() == null)
        System.out.println("Second number is invalid");
    else
        System.out.println("Second number is " + myNumber2.getNumber());

 }

 public static void main(String... args) {
    validatePhoneNumber("123-456-7890", "456-7890");
 }
}

6 个答案:

答案 0 :(得分:0)

如果您声明

Integer numberLength=new Integer(7);

您以后仍可以为numberLength分配另一个值。如果在内部类中使用numberLength,则不允许这样做。

答案 1 :(得分:0)

最终运算符实际上并不要求它所作用的变量为immutible。它实际上只是强制变量不是reassignable。即使Integer本身为Integer,您也可以在immutible类型的情况下重新分配变量。

答案 2 :(得分:0)

内部类可以从其封闭的类中访问成员。但是,在您的示例中,numberLength不是类成员,而是变量,因此对于类PhoneNumber是不可访问的,除非声明为静态。

答案 3 :(得分:0)

为了使局部变量对内部类的方法可见,编译器必须将变量的值复制到内部类可以访问它的位置。对同一变量的引用可以在不同的地方使用不同的代码序列,只要在任何地方生成相同的值,以便名称始终在其范围的所有部分中引用相同的变量。

按照惯例,像数组这样的局部变量被复制到内部类的私有字段val $数组中。 (因为数组是final,所以这些副本永远不会包含不一致的值。)每个复制的值都作为同名的单独参数传递给内部类构造函数。

答案 4 :(得分:0)

在下一行中,如果U这样指定,

numberLength=12;

您丢弃了之前的值并创建了一个值为12的新numberLength对象。之前的值无法更改,而是创建新实例。但如果将其指定为final,则无法覆盖它的值。

答案 5 :(得分:0)

如果声明本地类引用了封闭范围中的变量,则编译器会在该本地类中生成一个(隐藏)字段,在该字段中复制已使用变量的值。也就是说,编译器必须确保不能更改变量的值。因此,变量必须是final,因为这是确保值固定的关键字。

总结:类Integer是最终的(它是不可变概念的一部分)并不重要。您引用的变量必须声明为final。