o instanceof TestPrintStream1 instanceof 这个运算符你搞清楚了吗?
if () 后面不使用花括号时,里面不能出现声明,因为那个涉及到作用域,而没有花括号又没有作用域了。个人理解。boolean ok = true; if(ok) MyClass c = new MyClass();这样也是不允许的。 改成MyClass c = null; if(ok) c = new MyClass(); 这样是可以的这个代码问题和 instanceof 没有任何关系http://www.java2000.net/p8891
SAGEZK☆老K(XXXXXX) 09:37:46 Java 把 Test tt = new Test(); 当两条语句看待了相当于 Test tt; tt = new Test();这个解释我不能接受,Test不能解析,我总不能理解。哈哈。
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 错误
也是哈,如果就一行去声明的话,解析的时候应该是Test tt; tt = new Test(); 那也就是拆成俩句了,先不管合理不合理,Test tt;应该为IF语句下的第一行,那么就是说tt = new Test(); 在引用tt时应该是无效的,因为它被声明在了IF语句里,而tt的引用是错误的,不在一个域里面,个人见解,哈哈
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 等语句后面加 上 { },哪怕块中的语句只有一行。
int i = 1; } 在C、 c++ 和C#中都是正确的,即使在Vs2005中这样的Java代码也是正确的,因为这种形式的代码在不同的编译方法中会有不同的解释(比如这样的形式 i 的作用域被默认为与if(){}形式中的一样。那么这样的形式就会正确)。从这可以看出,1、编写代码时,尽可能的与规范靠拢,2.熟悉自己用得编译器
学习了支持Java 把 Test tt = new Test(); 当两条语句看待了相当于 Test tt; tt = new Test();
不管是JAVA还是C,不管是不是一句话,都要加括号。
果子的解释还说服不了我。如你所说,分号是一句的结尾,那么为什么变成了2句而不是一句。 if(true)Test t = null;这总是一句了吧;可以依然报错。—————————————————————————————————————————————— Test t = null 这里 t 的作用范围是在 if 的外层块中,并不在 if 之中,就算把它们合并为一行, 但是这样骗不了编译器,编译器并不是按书写格式来进行语法判断的。由于 t 的作用范围,在编译器看来与 if 属于同一个块当中的,并不属于 if 语句中的,所以编译器会 认为这个 if 语句并没有结束。局部变量声明作为一条语句不能出现在 if, while, do, for 当中。
初步认为 对eclipse而言 if without braces 不允许初始化语句的出现 其中Type(TestPrintStream1)无法解析只是eclipse一个权宜表错方式 因为单单判VariableDeclarators(tt)无法解析貌似很不合道理 毕竟此时Type可以Open Declaration而且其上的首个错误提示是Syntax error, insert "AssignmentOperator Expression" to complete Assignment 更清晰的表明了立场 此处只需要纯赋值语句 而不用任何附加Type 出现就报“不认”
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) { 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.熟悉自己用得编译器 以上是对这个问题的实质性解释。如有疑问请看看有关编译原理的书。编译原理会告诉你代码是怎样运行的。
楼上? if (o instanceof TestPrintStream1) TestPrintStream1 tt = (TestPrintStream1) o; ----------------------------------------------------------------------- if (o instanceof TestPrintStream1) { TestPrintStream1 tt; }
后面不使用花括号时,里面不能出现声明,因为那个涉及到作用域,而没有花括号又没有作用域了。个人理解。boolean ok = true;
if(ok)
MyClass c = new MyClass();这样也是不允许的。
改成MyClass c = null;
if(ok)
c = new MyClass();
这样是可以的这个代码问题和 instanceof 没有任何关系http://www.java2000.net/p8891
Java 把 Test tt = new Test(); 当两条语句看待了相当于 Test tt; tt = new Test();这个解释我不能接受,Test不能解析,我总不能理解。哈哈。
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 错误
块内,也可以理解为在“{ }”内。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 等语句后面加
上 { },哪怕块中的语句只有一行。
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();
} }
}
嗯..理解理解.
相当于:
if (o instanceof TestPrintStream1) {
TestPrintStream1 tt;
}
tt = (TestPrintStream1)o;
new Object();
并不报错。但是if (true)
int a;if (true)
int a=3;
也都报了类似的问题。
接触过vb的朋友也知道,vb有块if语句和行if语句,虽然java没有明确提到,但是if (true) statemenet;就是行if语句。行内的作用域与if所在作用域相同。因为作用域是由{}决定的。只是lz提到的问题很难碰到(如果严格参考java规范的化),所有平时也没人会去考虑。当然我无法证明这个作用域究竟是什么!这是我的理解。
即: if (o instanceof TestPrintStream1) TestPrintStream1 tt = (TestPrintStream1) o;
----------------------------------------------------------------------------------
的话,是不是编译器就可编译通过?
不是,编译器并不是从代码的书写格式来看的,而是按照规定死了的作用范围来判断的,与代码的格式毫无关系。
因为,编译器把 if 后面的那句 tt 的变量声明看作是 try 块中的,并不是 if 中的,所以就算写在一行当中,
还是会报 if 语句没有结束这种让人摸不着头脑的错误。
if(true)Test t = null;这总是一句了吧;可以依然报错。
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
{
int j = 0;
if (j == 0)
int i = 1;
}
在C、 c++ 和C#中都是正确的,即使在Vs2005中这样的Java代码也是正确的,因为这种形式的代码在不同的编译方法中会有不同的解释(比如这样的形式 i 的作用域被默认为与if(){}形式中的一样。那么这样的形式就会正确)。从这可以看出,1、编写代码时,尽可能的与规范靠拢,2.熟悉自己用得编译器
Test t = null 这里 t 的作用范围是在 if 的外层块中,并不在 if 之中,就算把它们合并为一行,
但是这样骗不了编译器,编译器并不是按书写格式来进行语法判断的。由于 t 的作用范围,在编译器看来与 if 属于同一个块当中的,并不属于 if 语句中的,所以编译器会
认为这个 if 语句并没有结束。局部变量声明作为一条语句不能出现在 if, while, do, for 当中。
其中Type(TestPrintStream1)无法解析只是eclipse一个权宜表错方式 因为单单判VariableDeclarators(tt)无法解析貌似很不合道理
毕竟此时Type可以Open Declaration而且其上的首个错误提示是Syntax error, insert "AssignmentOperator Expression" to complete Assignment 更清晰的表明了立场 此处只需要纯赋值语句 而不用任何附加Type 出现就报“不认”
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();
} }
}
这样就行了,不加括号应该定义成员变量
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.熟悉自己用得编译器
以上是对这个问题的实质性解释。如有疑问请看看有关编译原理的书。编译原理会告诉你代码是怎样运行的。
TestPrintStream1 tt = (TestPrintStream1) o; ----------------------------------------------------------------------- if (o instanceof TestPrintStream1) {
TestPrintStream1 tt;
}
tt = (TestPrintStream1) o;