1

In the java 8 tutorial on local class it says the following about local class in static methods:

Local classes are similar to inner classes because they cannot define or declare any static members. Local classes in static methods, such as the class PhoneNumber, which is defined in the static method validatePhoneNumber, can only refer to static members of the enclosing class. For example, if you do not define the member variable regularExpression as static, then the Java compiler generates an error similar to "non-static variable regularExpression cannot be referenced from a static context."

Local classes are non-static because they have access to instance members of the enclosing block. Consequently, they cannot contain most kinds of static declarations.

I am confused by the error message in paragraph 1 and what is stated in paragraph 2, why the local class is considered static context but itself is non-static? Local variables and parameters in static methods are not intended for use with class instance, so why can't we make a local class in static method static?

The example it uses is shown below

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

For the following code sample, I am able to access printMember() of AnotherClass from the static method localMethod() of the class LocalClassTest, so I am assuming that even the local class is declared static, I can still access enclosing class' static members with class reference

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);
    }
}

Thanks for your help.

Community
  • 1
  • 1
Derek Xie
  • 111
  • 1
  • 8
  • 2
    Please add exact text from links inside blocks so that people are able to read firsthand what's given(besides, links can go dead). It'll also improve readability of your question. – cst1992 Feb 08 '18 at 05:00
  • 1
    'Because they have access to instance members of the enclosing block': no they don't. They have access to *local variables* and *parameters* of the enclosing block. Nothing to do with instances whatsoever. You're just misquoting your source. – user207421 Feb 08 '18 at 05:14
  • There is no need to have a syntax support to have static keyword for a local class, because, without making the local class as static it can access the static members of enclosing class. – Loganathan Feb 08 '18 at 07:34
  • "Local classes are non-static because they have access to instance members of the enclosing block." if the block static so it have acess inside the block, if it is not so it have access to the class – Marcos Vasconcelos Feb 08 '18 at 13:05
  • @EJP he's not misquoting. The quote comes straight out of Oracle's tutorial which is linked in the question. – DodgyCodeException Feb 08 '18 at 13:08
  • @MarcosVasconcelos. Hello Macros, but if I can access static members of one class through class reference from static method of another class, shouldn't I also be able to access static members of the enclosing class from within a local class with class reference if it were declared static? Thanks for your help. – Derek Xie Feb 08 '18 at 13:32
  • Didnt understood your question, make a sample for us, but yes, it should, but static member access is usually with the ClassName.staticMember – Marcos Vasconcelos Feb 08 '18 at 13:36
  • @MarcosVasconcelos. Hello Marcos, I have added some sample code to clarify what I meant. I am assuming if I can refer to static method in one class from static method in another class, I should be able access static class members of the enclosing class if the local class is declared static when I use class reference. Thanks – Derek Xie Feb 08 '18 at 17:16
  • 1
    The static variable is not from any instance, it is static. Yes you can access any static member in any static context (according to visibility of course) – Marcos Vasconcelos Feb 08 '18 at 17:28
  • 1
    static is a virus keyword, if you remove it from the name inside the non-static AnotherClass you will see that you can't use it at printMembers(), removing it you will not be able to call from class name and will need a instance, cause in this case it will be a instance member and not static. – Marcos Vasconcelos Feb 08 '18 at 17:31
  • @MarcosVasconcelos It is true that when I remove the static keyword from printMembers(), I will not be able to access it from within localMethod(), but according to Oracle's tutorial, local class in static methods can only get access to static members of the enclosing class, that means they only need to access static fields, I don't understand why they cannot make it static. Or they could make it static but it would be useless to have a static local class? Thanks. – Derek Xie Feb 08 '18 at 17:55
  • Static local class would have some uses when creating a type without context, in the way it is done, you have access to variables in the context, so the final variables in the static method (context) is acessible in the local class – Marcos Vasconcelos Feb 08 '18 at 18:00
  • A class declared in static scope (static methods) will always be of static context andone in instance scope will always be of scope. – Marcos Vasconcelos Feb 08 '18 at 18:03
  • @MarcosVasconcelos Marcos, thank you so much for the explanation. – Derek Xie Feb 08 '18 at 18:44
  • Wished to add as an answer, but too much text – Marcos Vasconcelos Feb 08 '18 at 18:48

1 Answers1

1

"Local classes are non-static because they have access to instance members of the enclosing block." - if the block is static so it have acess inside the block, if it is not so it have access to the class.

A static variable is not from any instance, it is static. You can access any static member in any static context (according to visibility of course).

Static is a virus keyword, if you remove it from the name inside the non-static AnotherClass you will see that you can't use it at printMembers(), removing it you will not be able to call from class name and will need a instance, cause in this case it will be a instance member and not static.

A static local class would have some uses when creating a type without context, in the way it is done, you have access to variables in the context, so the final variables in the static method (context) is acessible in the local class.

In a non static block, the local class will always be of instance and have access to the methods of the outer class.

Marcos Vasconcelos
  • 18,136
  • 30
  • 106
  • 167