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

时间:2015-05-04 03:16:43

标签: java oop casting

我想知道为什么在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 
   }
}

4 个答案:

答案 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 
  }
}