我想知道为什么在obj = w;
之后引用“w”会引发错误。你是不是只是通过说obj = w来创建另一个指向那个w实例的指针?即为什么说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
}
}
答案 0 :(得分:4)
早上第一件事就是引用JLS。
JLS 6.3。宣言的范围:
块中的局部变量声明的范围(第14.4节)是声明出现的块的其余部分,从其自己的初始化器开始,并包括局部变量声明语句中右侧的任何其他声明符。 / p>
和
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
。
答案 1 :(得分:1)
这是范围的问题。
的范围{
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 } }
答案 2 :(得分:0)
变量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);
}
}
答案 3 :(得分:0)
正如在其他答案中提到的那样,删除括号将起作用。如果要保留括号,也可以按照以下方式进行操作。实际上在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
}
}