在if语句中创建对象并在以后使用它

我正在为Infix表示法编写一个Parser。 在if语句中,我声明了变量newchild。 否则我希望它抛出exception。 但是当我超出范围时,编译器不再知道变量。 我无法在if语句之前声明它,因为根据我们所处的情况,变量被赋予不同的数据类型。

我该怎么做才能解决这个问题?

public class ParserForInfixNotation { public Node parse(List tokenList) { Stack myStack = new Stack(); int i =1; while(i  i+3){ //die Klammer muss mindestens 2 Stellen enthalten anzahlklammern--; j++; } else if(tokenList.get(j) == "("){ anzahlklammern++; j++; } else if ((Character.isDigit(tokenList.get(j).charAt(1))) || tokenList.get(j) == "+" || tokenList.get(j) == "*" || tokenList.get(j) == "-"){ j++; } else{ throw new IllegalArgumentException(); } } List neu = new ArrayList(); for (int l = i+2; l i+5){ //die Klammer muss mindestens 2 Stellen enthalten anzahlklammern--; j++; } else if(tokenList.get(j) == "("){ anzahlklammern++; j++; } else if ((Character.isDigit(tokenList.get(j).charAt(1))) || tokenList.get(j) == "+" || tokenList.get(j) == "*" || tokenList.get(j) == "-"){ j++; } else{ throw new IllegalArgumentException(); } } List neu = new ArrayList(); for (int l = i+4; l i+3){ //die Klammer muss mindestens 2 Stellen enthalten anzahlklammern--; j++; } else if(tokenList.get(j) == "("){ anzahlklammern++; j++; } else if ((Character.isDigit(tokenList.get(j).charAt(1))) || tokenList.get(j) == "+" || tokenList.get(j) == "*" || tokenList.get(j) == "-"){ j++; } else{ throw new IllegalArgumentException(); } } List neu = new ArrayList(); for (int l = i+2; l j+5){ //die Klammer muss mindestens 2 Stellen enthalten anzahlklammern--; k++; } else if(tokenList.get(k) == "("){ anzahlklammern++; k++; } else if ((Character.isDigit(tokenList.get(k).charAt(1))) || tokenList.get(k) == "+" || tokenList.get(k) == "*" || tokenList.get(k) == "-"){ k++; } else{ throw new IllegalArgumentException(); } } List neu2 = new ArrayList(); for (int l = j+4; l<k;l++){ neu.add(tokenList.get(l)); } Node newrightchild = parse(neu2); } else if(Character.isDigit(tokenList.get(j+2).charAt(1))){ Leaf newrightchild = new Leaf(Integer.parseInt(tokenList.get(j+2))); } else{ throw new IllegalArgumentException(); } } BinaryOpNode res = new BinaryOpNode(operator, newleftchild, newrightchild); } else{ throw new IllegalArgumentException(); } } else{ throw new IllegalArgumentException(); } } return res; } 

这是关于范围的 。 变量的范围是声明它的块,并在其中阻塞。 块是否是if语句的块,其他一些语句,或者只是为了定义范围而放在那里的块并不重要。

你遇到这个问题:

 { Leaf leaf = new Leaf(); } doSomethingWith(leaf); // compiler error - there is no `leaf` in this scope. 

你可以修复它:

  Leaf leaf; { leaf = new Leaf(); } doSomethingWith(leaf); 

如果有可能不会发生对leaf的赋值 – 例如,如果它在if块中,那么你将得到编译器错误,表明variable leaf may not have been initialized 。 您可以通过首先初始化为某些回退值来解决此问题。 它通常为空:

  Leaf leaf = null; if(...) { leaf = new Leaf(); } doSomethingWith(leaf); 

但是现在你的代码必须处理leaf == null的可能性 – 这导致代码过于复杂或脆弱。 找到避免分配null的方法,或者如果不能,则保持易受攻击的代码块被隔离,以便该范围之外的任何内容都不需要处理null变量的可能性。

你可以做:

 int value = = -1; Leaf res = null; if(Character.isDigit(tokenList.get(i).charAt(1))){ value =Integer.parseInt(tokenList.get(i)); res = new Leaf(value); } 

并检查变量res中存储的值是否存在

一种方法是移动/复制这一行:

 UnaryOpNode res = new UnaryOpNode('-',newchild); 

因此它包含在If和else中,如果是这样的话:

 if((Character.isDigit(tokenList.get(j).charAt(1))) || (tokenList.get(j+1) == ")")) { Leaf newchild = new Leaf(Integer.parseInt(tokenList.get(j))); UnaryOpNode res = new UnaryOpNode('-',newchild); } else if(tokenList.get(j) == "("){ while(!end){ if(tokenList.get(j) == ")" && anzahlklammern == 1){ end = true; } else if(tokenList.get(j) == ")" && j > i+3){ anzahlklammern--; j++; } else if(tokenList.get(j) == "("){ anzahlklammern++; j++; } else if ((Character.isDigit(tokenList.get(j).charAt(1))) || tokenList.get(j) == "+" || tokenList.get(j) == "*" || tokenList.get(j) == "-"){ j++; } else{ throw new IllegalArgumentException(); } } List neu = new ArrayList<>(); for (int l = i+2; l