为什么静态方法中的本地类不是静态的

时间:2018-02-08 04:54:21

标签: java

local class的java 8教程中,它描述了静态方法中的本地类:

  

本地类与内部类相似,因为它们无法定义或声明任何静态成员。静态方法中的本地类,例如在静态方法validatePhoneNumber中定义的类PhoneNumber,只能引用封闭类的静态成员。例如,如果未将成员变量regularExpression定义为static,则Java编译器会生成类似于“非静态变量regularExpression无法从静态上下文引用”的错误。

     

本地类是非静态的,因为它们可以访问封闭块的实例成员。因此,它们不能包含大多数静态声明。

我对第1段中的错误消息和第2段中说明的内容感到困惑,为什么本地类被认为是静态上下文但本身是非静态的?静态方法中的局部变量和参数不适用于类实例,那么为什么我们不能在静态方法中创建静态方法?

它使用的示例如下所示

public class LocalClassExample {

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

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

        final int numberLength = 10;

        // 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 numbers 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");
    }
}

对于下面的代码示例,我能够从类LocalClassTest的静态方法localMethod()访问AnotherClass的printMember(),所以我假设即使本地类声明为static,我仍然可以访问封闭类'具有类引用的静态成员

public class LocalClassTest {

    private static final int INTEGER = 9;
    private static String name = "foo";

    public static void localMethod() {
        int localInt = 5;
        //Accessing class variables of its own class
        System.out.println("name = " + LocalClassTest.name + " and INTEGER = " + LocalClassTest.INTEGER);
        //Accessing class variables of another class
        //If a static method can access static members of another class,
        //why cann't we declare a local class static and access class variable through class reference?
        AnotherClass.printMembers();
        class LocalClass {
            public void printAccess() {
                System.out.println("Variable of local static method, localInt = " + localInt);
                // if the localClass were static, would I be able to access class variable name
                // through class reference LocalClassTest.name?
                System.out.println("Class variable of enclosing class, name = " + name);
            }
        }
        LocalClass obj1 = new LocalClass();
        obj1.printAccess();
    }
    public static void main(String[] args) {
        LocalClassTest.localMethod();


    }

}

class AnotherClass {
    public static String name = "class variable from another class";

    public static void printMembers() {
        System.out.println("name = " + AnotherClass.name);
    }
}

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

"本地类是非静态的,因为它们可以访问封闭块的实例成员。" - 如果块是静态的,那么它在块内有访问权,如果不是这样,它就可以访问该类。

静态变量不是来自任何实例,而是静态的。您可以在任何静态上下文中访问任何静态成员(根据课程的可见性)。

静态是一个病毒关键字,如果你从非静态的AnotherClass中的name中删除它,你会看到你无法在printMembers()中使用它,删除它你将无法从类名调用并需要一个实例,因为在这种情况下它将是一个实例成员而不是静态的。

静态本地类在创建没有上下文的类型时会有一些用处,就像它完成的那样,你可以访问上下文中的变量,所以静态方法(context)中的最终变量在本地是可访问的类。

在非静态块中,本地类将始终是实例,并且可以访问外部类的方法。