【问题标题】:Compilation error String cannot be resolved to a variable编译错误字符串无法解析为变量
【发布时间】:2018-02-21 07:59:09
【问题描述】:
public class StrTest {

    public static void main(String[] args) {
        int i = 10;
        Object obj =i;
        if(obj instanceof String)
        String s=(String) obj;
    }
}

给我错误“字符串无法解析为变量”,但是如果将程序更改为

public class StrTest {

    public static void main(String[] args) {
        int i = 10;
        Object obj =i;
        String s=null;
        if(obj instanceof String)
        s=(String) obj;
    }
}

如果我做这样的事情,这实际上编译得很好:

public class StrTest {

    public static void main(String[] args) {
        int i = 10;
        Object obj =i;
        if(obj instanceof String){
            String s=(String) obj;
        }

    }
}

这也很好用。我想知道有什么语法错误。

【问题讨论】:

  • if(obj instanceof String) String s=(String) obj; 将是完全无用的代码,不是吗
  • @scary wombat :我同意,但我唯一的问题是为什么错误显示“字符串无法解析为变量”

标签: java string if-statement


【解决方案1】:

我无法重现“字符串无法解析为变量”错误,您的代码给我的是这个编译错误,所以我将重点关注它:

StrTest.java:7: error: variable declaration not allowed here
        String s=(String) obj;

在 Java 中

if(obj instanceof String) 
    String s=(String) obj;

类似于

if(obj instanceof String) {
    String s=(String) obj;
}

变量的范围仅限于代码块{..}声明了。这意味着我们不能在该块之外的任何地方使用s 变量。拥有变量的另一个主要原因是能够在不同的地方使用它们的值,比如int x = readSomeData(); int y = 2*x;。但是由于我们没有在其他任何地方使用该变量,编译器将其视为不必要的代码(可能是由某些误解造成的),因此它试图通过给出错误来阻止我们编写它。

顺便说一句 Andy Turner pointed out in his comment 在技术上可以使用 s 在同一行中,例如

public static String someMethod(String a, String b){return a+b;}
...

if(obj instanceof String) 
    String s = someMethod(s = "foo", s);
// we are "using" value of s here ---^

但编译器更关注的是

if(obj instanceof String) 
    String s = ...;
//we still CAN'T use "s" variable *after* that line

您的其他情况问题已解决

String s=null;
if(obj instanceof String)
    s=(String) obj;

Object obj =i;
if(obj instanceof String){
    String s=(String) obj;
}

因为s/objmain 方法中声明,所以这些变量在if 部分之后也可用,仅分配新值给他们。

顺便说一句,你可以明确写{..}

if(obj instanceof String) {
    String s=(String) obj;
}

这样的代码编译,因为编译器假设你知道s的范围(你可能只是得到关于冗余变量的警告

【讨论】:

  • “既然声明 s 没有真正的价值”,那么有一种非常晦涩的方式可以让你使用它,如果它被允许。模糊到“没有真正价值”实际上是真的,但严格来说可能存在一些价值。
  • (我在想String s = someMethodTakingStringParams(s = expensiveMethodReturningString(), s);)。
  • @AndyTurner 谢谢,我没想到这种可能性。我试图澄清一下我的答案,但可能需要更进一步地改写它以包含您的示例(我试图避免这样做,以免使事情过于复杂)
  • 感谢 Andy 和 Pshemo 的澄清。我只是在想它为什么会发生,实际上它是有道理的,因为如果我在它只会编译下一行之后不使用大括号,并且该变量的范围就是那一行。但是如果我在那行之后写一个 Lambda 函数,那它会怎么看。
猜你喜欢
  • 2012-11-20
  • 1970-01-01
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
  • 2013-08-27
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
相关资源
最近更新 更多