为什么这个Java转换会抛出错误?

我想知道为什么在obj = w;之后引用“w” obj = w; 会抛出错误。 你是不是只是通过说obj = w来创建另一个指向该w实例的指针? 也就是说,为什么说String s = "hi"; String w = s;String s = "hi"; String w = s;东西是不同的String s = "hi"; String w = s; String s = "hi"; String w = s; 谢谢!

 public class Casting { public static void main(String[] args) { // casting doesn't change the object Object obj; { Stopwatch w = new Stopwatch(); obj = w; } System.out.println(obj); // this line does work System.out.println(w); //this line does not work } } 

没有什么比早上引用JLS的第一件事了。

JLS 6.3。 宣言范围:

块(第14.4节)中局部变量声明的范围是声明出现的块的其余部分,从其自己的初始化程序开始,并在本地变量声明语句中包含右侧的任何其他声明符。

JLS 14.2。 块:

是大括号内的语句,本地类声明和局部变量声明语句的序列。

你的情况意味着什么? 局部变量w在块中声明

 { Stopwatch w = new Stopwatch(); obj = w; } 

(“它自己的初始值设定项”是块中的第一行),因此其范围是该块的其余部分。 对它的引用,

 System.out.println(w); 

在块之外,因此w将无法解析为变量。

那么局部变量obj呢? 它在街区宣布

 public static void main(String[] args) { Object obj; { Stopwatch w = new Stopwatch(); obj = w; } System.out.println(obj); System.out.println(w); } 

在这种情况下,它是一个方法块。 电话

 System.out.println(obj); 

在块内,因此可以成功引用obj

这是范围的问题。范围

 { Stopwatch w = new Stopwatch(); obj = w; } 

这里w范围在括号内,并且这个变量在外面是不可访问的。所以这里没有赋值问题,但问题与范围有关,可以通过

 public class Casting { public static void main(String[] args) { // casting doesn't change the object String w; Object obj; { w = new String(); obj = w; } System.out.println(obj); // this line does work System.out.println(w); //this line now working } } 

变量w在块内声明,因此在块之外它不存在。 这个问题与铸造无关。 删除大括号,它将工作:

 public class Casting { public static void main(String[] args) { // casting doesn't change the object Object obj; Stopwatch w = new Stopwatch(); obj = w; System.out.println(obj); System.out.println(w); } } 

正如在其他答案中提到的那样,删除括号将起作用。 如果要保留括号,也可按以下方式操作。 实际上在java中,变量有范围,一个变量可以在声明它的范围内使用。 就像在“if”块或“try”块中声明一些变量一样,它只能在该范围内使用。 这有助于有效的垃圾收集。 并且总是最好在最小所需范围内定义变量但是,如果要在某个地方创建某个对象但是想在该部分(块)之后使用它,则在块外部声明(变量不必创建对象)。

 public class Casting { public static void main(String[] args) { // casting doesn't change the object Object obj; Stopwatch w ; { w = new Stopwatch(); obj = w; } System.out.println(obj); // this line does work System.out.println(w); //this line does not work } }