Область действия локальной переменной для анонимного класса, объявленного в методе

public class TestThread
{
    public static void main (String [] args) 
    {
        Foo f = new Foo();
        Thread t = new Thread(new Runnable() 
        {
            public void run() 
            {
                f.doStuff();
            }
        });
        Thread g = new Thread() 
        {
            public void run() 
            {
                f.doStuff();
            }
        };
        t.start();
        g.start();
    }
}
class Foo 
{
    public void doStuff() 
    {}
}

Мы знаем, что локальная переменная функции не находится в области видимости, пока работает другой метод, и мы также знаем, что локальный внутренний класс метода может использовать только конечную переменную метода. Мой вопрос в том, почему этот код компилируется и запускается, хотя f является локальной переменной и даже не финальной. Это должно выходить за рамки анонимных внутренних классов...


person Madhurendra Narayan Tiwary    schedule 13.09.2015    source источник
comment
какой у вас здесь вопрос ›? f является объектом типа Foo..., это имело бы больше смысла, если бы, например, вы объявили String x во внешнем классе и спросили, почему она доступна внутри класса Foo...   -  person QuakeCore    schedule 13.09.2015
comment
@abhishekbafna: такой странный комментарий от пользователя с твоей репутацией... это java 101!   -  person QuakeCore    schedule 13.09.2015
comment
@abhishekbafna серьезно?, вот что не так   -  person QuakeCore    schedule 13.09.2015
comment
и да, код не скомпилируется, f должен быть сделан окончательным ионным порядком, чтобы он скомпилировался кстати   -  person QuakeCore    schedule 13.09.2015
comment
@QuakeCore Это произошло из-за опечатки при создании java-файла. Простите за это. Спасибо, что подняли это.   -  person YoungHobbit    schedule 13.09.2015
comment
Код не компилируется. Error:(10, 9) java: local variable f is accessed from within inner class; needs to be declared final.   -  person YoungHobbit    schedule 13.09.2015


Ответы (2)


public class TestThread
{
     boolean innerClassCanSeeMe =true;
    public static void main (String [] args) 
    {
        boolean  accessible=false;
        final Foo f = new Foo();
        Thread t = new Thread(new Runnable() 
        {
            public void run() 
            {
                f.doStuff();
            }
        });
        Thread g = new Thread() 
        {
            public void run() 
            {
                f.doStuff();
            }
        };
        t.start();
        g.start();
    }
}
class Foo 
{
    public void doStuff() 
    {
        System.out.println(  TestThread.innerClassCanSeeMe);//yay error, unless you make innerClassCanSeeMe static.
       System.out.println( new TestThread().innerClassCanSeeMe);
    }
}

Я настоятельно рекомендую вам поработать над ООП, вы можете начать отсюда, и это не прямой ответ на ваш вопрос, но если вы потратите пару часов на этот урок, я думаю, вы сможете ответить сами себе, и я даже проголосую за вас, если вы ответите себе в течение 24 часов: )

person QuakeCore    schedule 13.09.2015

f фактически окончательный; согласно документации Oracle по локальным классам:

Однако, начиная с Java SE 8, локальный класс может обращаться к локальным переменным и параметрам включающего блока, которые являются окончательными или фактически окончательными. Переменная или параметр, значение которого никогда не изменяется после инициализации, фактически являются окончательными.

person Rafal    schedule 13.09.2015