2015-06-30 4 views
0

Проблема в found = true; линииJava - Доступ к локальной переменной из анонимного класса

public boolean containsBlock(String nodeName, ASTNode node) 
{ 
    boolean found = false; 
    if(nodeName.equals("if")) 
    { 
     node.accept(new ASTVisitor() 
     { 
      public boolean visit(IfStatement s) 
      { 
       found = true; 
       return false; 
      } 
     }); 
    } 
    return found; 
} 

Я знаю, что я буду иметь возможность получить доступ к этому, если я делаю found глобальной переменной класса, но я не хочу сделать это. Может быть, есть другой способ? Мне просто нужно, чтобы другой код знает, что что-то было найдено

UPD: Является ли этот код лучше и вернуть правую

public boolean containsBlock(Text nodeName, ASTNode node) 
{ 
    final AtomicBoolean flag = new AtomicBoolean(false); 
    Thread thread = new Thread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      if(nodeName.matches("if")) 
      { 
       node.accept(new ASTVisitor() 
       { 
        public boolean visit(IfStatement s) 
        { 
         flag.set(true); 
         return false; 
        } 
       }); 
      } 
      else 
       throw new RuntimeException("Unknown NodeName: " + nodeName); 
     } 
    }); 
    thread.start(); 
    try { 
     thread.join(); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return flag.get(); 
} 
+0

Я не думаю, что это возможно. Что вы на самом деле пытаетесь сделать? Я чувствую проблему XY. – markspace

+0

@markspace, Это метод анализа исходного кода. Я пытаюсь обнаружить некоторые элементы в 'ASTNode' (если инструкции, операторы цикла, операторы блоков и т. Д.). Что мы будем искать, зависит от 'nodeName'. Если что-то найдено в данной части исходного кода, мы должны знать об этом и изменять переменную флага и возвращать результат. – ivan

+0

@ivan ваш флаг бесполезен. Если код будет выполнен не по порядку (что, вероятно, имеет место здесь, так как я подозреваю, что вы либо отложили, либо асинхронный вызов здесь), вы получите false, возвращенный практически все время (если у вас нет обработки ASTNode в другом потоке , плюс это должно быть * молниеносно *, помните меня). Если вы хотите, чтобы флаг работал, вам необходимо, например, сделайте его постоянными данными, создав для него внешнее поле и пропустив «возврат» в целом. Нелинейный код (даже не многопотоковый, шаблон посетителя включен) не работает так, как это происходит синхронно, линейно. – vaxquis

ответ

3

При передаче ASTVisitor экземпляра к экземпляру ASTNode (с помощью акцепта метод), он не выполняет ваш метод visit немедленно. Поэтому нет смысла пытаться изменить локальную переменную вашего метода containsBlock с помощью метода visit.

visit, скорее всего, будет выполнен после возврата метода containsBlock, после чего ваша локальная переменная found больше не будет находиться в стеке вызовов.

+0

Yup. Именно здесь и ИМО. Доступ к внешней области для чтения - это одно: это можно сделать и делать регулярно. Доступ к ней для записи бесполезен, если на данные нельзя ссылаться снаружи, что будет представлять собой переменную поля, которая не нуждается в каком-либо специальном обеспечении, которое будет использоваться внутри анонимного. – vaxquis

+0

Да, но как сделать так, чтобы это было выполнено немедленно? – ivan

+1

@ivan Я не знаком с этими классами, но из найденного Javadoc «ASTNode» вызывает метод «посещения» «ASTVisitor», который был передан ему, когда вы доходите до экземпляра «ASTNode», итерации по дерево. Это стандартный шаблон дизайна посетителей. – Eran

Смежные вопросы