本帖最后由 java2000_net 于 2008-08-26 09:37:06 编辑

解决方案 »

  1.   

    o instanceof TestPrintStream1 instanceof 这个运算符你搞清楚了吗?
      

  2.   

    if ()
    后面不使用花括号时,里面不能出现声明,因为那个涉及到作用域,而没有花括号又没有作用域了。个人理解。boolean ok = true;
    if(ok)
      MyClass c = new MyClass();这样也是不允许的。
    改成MyClass c = null;
    if(ok)
      c = new MyClass();
    这样是可以的这个代码问题和 instanceof 没有任何关系http://www.java2000.net/p8891
      

  3.   

    SAGEZK☆老K(XXXXXX) 09:37:46
    Java 把 Test tt = new Test(); 当两条语句看待了相当于 Test tt; tt = new Test();这个解释我不能接受,Test不能解析,我总不能理解。哈哈。
      

  4.   

    难道是java中的bug,不过这样有个好处,就是使代码容易读
      

  5.   

    你声明变量的时候,应该确认你这个变量的作用域,很显示这行语句的作用域取决于上边的IF语句,但是你却没有规定IF语句的作用域,也就是{},你把IF语句删掉了,很显然,他的作用域变成了TRY{},所以你是删还是加都是对的,不过这种错还是你写作习惯不好,你要是IF语句作用域范围内不管有几行代码,你都加上{}就不会出现这种问题了
      

  6.   

    假设我们可以IF后面的唯一一行语句里进行声明,那这个声明有意义么?如果没有{},只能说你的IF语句的作用域就是他下边的一行,那你声明的变量有何意义?多此一举?
      

  7.   

    Eclipse 中报的语法错误是:
          Test cannot be resolved
          tt cannot be resolvedcmd 下 javac 没通过编译报的错误是:
    D:\Test.java:x: 不是语句
                            Test tt = new Test();
                            ^
    D:\Test.java:x: 需要 ';'
                            Test tt = new Test();
                                ^
    2 错误
      

  8.   

    也是哈,如果就一行去声明的话,解析的时候应该是Test tt;  tt = new Test(); 那也就是拆成俩句了,先不管合理不合理,Test tt;应该为IF语句下的第一行,那么就是说tt = new Test(); 在引用tt时应该是无效的,因为它被声明在了IF语句里,而tt的引用是错误的,不在一个域里面,个人见解,哈哈
      

  9.   

    Java Language Specification 明确指出局部变量声明的作用范围是在一个
    块内,也可以理解为在“{  }”内。for 循环可以不使用“{ }”的,但仅限于
    执行语句(其中并不包括变量声明语句)我们看到的代码是这样的:01  public class TestPrintStream1 {
    02
    03      public static void main(String[] args) {
    04
    05          Class c = TestPrintStream1.class;
    06          try {
    07              Object o = c.newInstance();
    08              if (o instanceof TestPrintStream1)
    09                  TestPrintStream1 tt = (TestPrintStream1) o;
    10          } catch (InstantiationException e) {
    11              e.printStackTrace();
    12          } catch (IllegalAccessException e) {
    13              e.printStackTrace();
    14          }
    15      }
    16  }由于变量作用域的关系,编译器所看到的代码是这样的,注意 09 行的缩进!01  public class TestPrintStream1 {
    02
    03      public static void main(String[] args) {
    04
    05          Class c = TestPrintStream1.class;
    06          try {
    07              Object o = c.newInstance();
    08              if (o instanceof TestPrintStream1)
    09              TestPrintStream1 tt = (TestPrintStream1) o;
    10          } catch (InstantiationException e) {
    11              e.printStackTrace();
    12          } catch (IllegalAccessException e) {
    13              e.printStackTrace();
    14          }
    15      }
    16  }从 08 和 09 行编译器所理解的代码中来看,很明显 08 行的 if 语句并没有
    结束,因此编译器会认为 if 后面少掉一个语句结束的分号。笨笨地编译器猜想你的代码应该是这样的,注意 08 行后面的分号08              if (o instanceof TestPrintStream1);
    09              TestPrintStream1 tt = (TestPrintStream1) o;实际上编译器的这种理解并不是我们想要的。为了不出现我们所不知的东西来困扰,应该老老实实地在 for, if, while 等语句后面加
    上 {  },哪怕块中的语句只有一行。
      

  10.   

    火龙果正解,参见《Java语言规范》(The Java Language Specification, Third Edition)http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html
      

  11.   

    public class Test {

    public static void main(String []args)
    {
    Class test=Test.class;
    try {
          Object o = test.newInstance();
          
          if (o instanceof Test)
            boolean bool=false;// 这里一样会报错,说boolean和 bool不能不解析
        } catch (InstantiationException e) {       e.printStackTrace();
        } catch (IllegalAccessException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } }
    }
    嗯..理解理解.
      

  12.   

    支持!!
    相当于:
      if (o instanceof TestPrintStream1) {
        TestPrintStream1 tt;
      } 
      tt = (TestPrintStream1)o;
      

  13.   

    各位,这里有没有熟悉C语言的朋友,相信大家都知道,在C语言里,变量的声明都是要出现在作用域的第一条非赋值语句前的。所以java也是c风格的语言,它也可能有类似的很细节的规则,就是,java的变量声明必须是一条语句。而java的每个作用域里面的语句分割符是“;”,if (true) statemenet;只是一条语句,并且如12楼所说,javac提示缺少;,因为它认为声明是一条新语句,而这里却不是。另一个方面javac在解析到单行if时会假设后面应该是个表达式之类或语句,而声明不是关键字,所以它报出无法解析。if (true)
        new Object();
    并不报错。但是if (true)
         int a;if (true)
         int a=3;
    也都报了类似的问题。
    接触过vb的朋友也知道,vb有块if语句和行if语句,虽然java没有明确提到,但是if (true) statemenet;就是行if语句。行内的作用域与if所在作用域相同。因为作用域是由{}决定的。只是lz提到的问题很难碰到(如果严格参考java规范的化),所有平时也没人会去考虑。当然我无法证明这个作用域究竟是什么!这是我的理解。
      

  14.   

    假设我们理解为是编译器判断出错,那我要是把语句变成一句,
    即:  if (o instanceof TestPrintStream1) TestPrintStream1 tt = (TestPrintStream1) o;
    ----------------------------------------------------------------------------------
    的话,是不是编译器就可编译通过?
      

  15.   


    不是,编译器并不是从代码的书写格式来看的,而是按照规定死了的作用范围来判断的,与代码的格式毫无关系。
    因为,编译器把 if 后面的那句 tt 的变量声明看作是 try 块中的,并不是 if 中的,所以就算写在一行当中,
    还是会报 if 语句没有结束这种让人摸不着头脑的错误。
      

  16.   

    如果那么清晰,我还会把它置顶并加精吗?因为我也没想到会这样。我的解释也是我猜测的。果子的解释还说服不了我。如你所说,分号是一句的结尾,那么为什么变成了2句而不是一句。
    if(true)Test t = null;这总是一句了吧;可以依然报错。
      

  17.   

    try {
          Object o = c.newInstance();
          
          if (o instanceof TestPrintStream1)
          {
            TestPrintStream1 tt = (TestPrintStream1) o;
           }
    }这样很明确,tt的作用域在if(){}的{}内({}是块作用域的标志)所以程序没有问题,而:
    try {
          Object o = c.newInstance();
          
          if (o instanceof TestPrintStream1)
            TestPrintStream1 tt = (TestPrintStream1) o;
    }编译器在编译这段代码时,当编译到TestPrintStream1 tt = (TestPrintStream1) o;时,会确定tt的作用域是在try{}的{}中。这明确几点,编译器在编译if语句时,并不对if语句表达式的对错作出判断,程序在执行时才对if语句表达式的对错做判断。还有就是编译器编译代码是顺序编译的。(这都是编译原理中的知识,这里要用到这些知识来解决这个问题)当编译器编译TestPrintStream1 tt = (TestPrintStream1) o;时,编译器不能确定是否会生成tt对象(因为if语句表达式的对错没有确定)并且编译器不能确定这句后是否会用到tt对象。这样就有可能出现:tt对象没有生成(if表达式错),而在TestPrintStream1 tt = (TestPrintStream1) o;的后面又要用到tt对象,这样程序会出错,也可能出现其他其他三种情况。但这已经不重要了,因为有了这种情况,tt的定义已经出现了歧义,所以编译器无法编译。这有很多解决方法。如果有谁还不清楚请联系我。 QQ:285743664
      

  18.   

    在做些说明:像以上的代码形式,
    {
    int j = 0;

    if (j == 0)
     
       int i = 1;
    }
    在C、 c++ 和C#中都是正确的,即使在Vs2005中这样的Java代码也是正确的,因为这种形式的代码在不同的编译方法中会有不同的解释(比如这样的形式 i 的作用域被默认为与if(){}形式中的一样。那么这样的形式就会正确)。从这可以看出,1、编写代码时,尽可能的与规范靠拢,2.熟悉自己用得编译器
      

  19.   

    估计不是程序的问题,以前我都出现过构造函数不能传参数的问题,后来是因为eclipse里导了一个错误的包,就产生了一些莫名其妙的错误.
      

  20.   

    学习了支持Java 把 Test tt = new Test(); 当两条语句看待了相当于 Test tt; tt = new Test(); 
      

  21.   

    不管是JAVA还是C,不管是不是一句话,都要加括号。
      

  22.   

    果子的解释还说服不了我。如你所说,分号是一句的结尾,那么为什么变成了2句而不是一句。 if(true)Test t = null;这总是一句了吧;可以依然报错。——————————————————————————————————————————————
    Test t = null 这里 t 的作用范围是在 if 的外层块中,并不在 if 之中,就算把它们合并为一行,
    但是这样骗不了编译器,编译器并不是按书写格式来进行语法判断的。由于 t 的作用范围,在编译器看来与 if 属于同一个块当中的,并不属于 if 语句中的,所以编译器会
    认为这个 if 语句并没有结束。局部变量声明作为一条语句不能出现在 if, while, do, for 当中。
      

  23.   

    初步认为 对eclipse而言 if without braces 不允许初始化语句的出现
    其中Type(TestPrintStream1)无法解析只是eclipse一个权宜表错方式 因为单单判VariableDeclarators(tt)无法解析貌似很不合道理
    毕竟此时Type可以Open Declaration而且其上的首个错误提示是Syntax error, insert "AssignmentOperator Expression" to complete Assignment 更清晰的表明了立场 此处只需要纯赋值语句 而不用任何附加Type 出现就报“不认”
      

  24.   

    public class TestPrintStream1 {   private static TestPrintStream1 tt; public static void main(String[] args) {     Class c = TestPrintStream1.class;
        try {
          Object o = c.newInstance();
          
          if (o instanceof TestPrintStream1)
            tt = (TestPrintStream1) o;// 这里为什么会报错呢,说tt 和 TestPrintStream1不能不解析
        } catch (InstantiationException e) {       e.printStackTrace();
        } catch (IllegalAccessException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }   }
    }
    这样就行了,不加括号应该定义成员变量
      

  25.   

    try { 
          Object o = c.newInstance(); 
          
          if (o instanceof TestPrintStream1) 
          { 
            TestPrintStream1 tt = (TestPrintStream1) o; 
          } 
    }这样很明确,tt的作用域在if(){}的{}内({}是块作用域的标志)所以程序没有问题,而: 
    try { 
          Object o = c.newInstance(); 
          
          if (o instanceof TestPrintStream1) 
            TestPrintStream1 tt = (TestPrintStream1) o; 
    }编译器在编译这段代码时,当编译到TestPrintStream1 tt = (TestPrintStream1) o;时,会确定tt的作用域是在try{}的{}中。这明确几点,编译器在编译if语句时,并不对if语句表达式的对错作出判断,程序在执行时才对if语句表达式的对错做判断。还有就是编译器编译代码是顺序编译的。(这都是编译原理中的知识,这里要用到这些知识来解决这个问题)当编译器编译TestPrintStream1 tt = (TestPrintStream1) o;时,编译器不能确定是否会生成tt对象(因为if语句表达式的对错没有确定)并且编译器不能确定这句后是否会用到tt对象。这样就有可能出现:tt对象没有生成(if表达式错),而在TestPrintStream1 tt = (TestPrintStream1) o;的后面又要用到tt对象,这样程序会出错,也可能出现其他其他三种情况。但这已经不重要了,因为有了这种情况,tt的定义已经出现了歧义,所以编译器无法编译。这有很多解决方法。 在做些说明:像以上的代码形式, 

    int j = 0; if (j == 0)   int i = 1; 

    在C、 c++ 和C#中都是正确的,即使在Vs2005中这样的Java代码也是正确的,因为这种形式的代码在不同的编译方法中会有不同的解释(比如这样的形式 i 的作用域被默认为与if(){}形式中的一样。那么这样的形式就会正确)。从这可以看出,1、编写代码时,尽可能的与规范靠拢,2.熟悉自己用得编译器 
    以上是对这个问题的实质性解释。如有疑问请看看有关编译原理的书。编译原理会告诉你代码是怎样运行的。
      

  26.   

    楼上?    if (o instanceof TestPrintStream1)
            TestPrintStream1 tt = (TestPrintStream1) o; -----------------------------------------------------------------------    if (o instanceof TestPrintStream1) {
            TestPrintStream1 tt;
        }
        
        tt = (TestPrintStream1) o;