黑马程序员技术交流社区

标题: if不加大括号{}竟然报错 [打印本页]

作者: hm372012    时间: 2015-6-21 21:48
标题: if不加大括号{}竟然报错
  1. abstract class Animal {
  2.         public abstract void eat();

  3.         public void method(Animal a) {
  4.                 if (a instanceof Dog)
  5.                         Dog d = (Dog) a;
  6.         }
  7. }

  8. class Dog extends Animal {
  9.         public void eat() {
  10.                 System.out.println("狗啃骨头...");
  11.         }

  12.         public void kanJia() {
  13.                 System.out.println("狗看家...");
  14.         }
  15. }

  16. class Cat extends Animal {
  17.         public void eat() {
  18.                 System.out.println("猫吃鱼...");
  19.         }

  20.         public void catchMouse() {
  21.                 System.out.println("猫捉老鼠...");
  22.         }
  23. }

  24. class DuoTai {
  25.         public static void main(String[] args) {

  26.                 Animal a = new Dog();
  27.                 a.method(a);
  28.         }
  29. }
复制代码
public void method(Animal a) {
if (a instanceof Dog)
Dog d = (Dog) a;
}
这里加{}程序就不报错,但不知为何会这样?求解




作者: iFmmer    时间: 2015-6-21 22:31
本帖最后由 iFmmer 于 2015-6-21 22:34 编辑

不知道你在问什么 你是说这样不报错吗
public void method(Animal a) {
    if (a instanceof Dog){
        Dog d = (Dog) a;
    }
}
你应该new一个Dog d = (Dog)a才行

作者: hm372012    时间: 2015-6-21 22:45
本帖最后由 hm372012 于 2015-6-22 00:40 编辑

这里转类型,不用new,下面加了大括号就不报错了
public void method(Animal a) {
    if (a instanceof Dog){
        Dog d = (Dog) a;
    }
}
作者: ARD    时间: 2015-6-21 23:30
没看懂 ,, if()如果不加括号只能控制一个语句.不会报错. 报错也是其他问题不会是if.
作者: g552092947    时间: 2015-6-21 23:34
我觉得,错不是错在if大括号那里
作者: bingyu    时间: 2015-6-21 23:34
应该不是if的问题吧
作者: guohaichang    时间: 2015-6-21 23:49
应该是这样的,局部变量声明是要在语句块里进行的。if后边不能是一个声明语句,应该跟一个执行语句。道理上讲,这样才有意义。如果是跟一个声明语句,就是条件编译了,不是if的菜,错就在这了。
作者: 双栖动物    时间: 2015-6-21 23:51
如果if后面只有一条语句 可以不加的
作者: JJJD    时间: 2015-6-22 00:12
来学习了。。。
作者: 我是隔壁老王呀    时间: 2015-6-22 06:14
iFmmer 发表于 2015-6-21 22:31
不知道你在问什么 你是说这样不报错吗
public void method(Animal a) {
    if (a instanceof Dog){

Dog d = (Dog) a;
这句可以分成两部分看待:
Dog d;
d = (Dog) a;
其实这句是没错的。
作者: 我是隔壁老王呀    时间: 2015-6-22 06:28
本帖最后由 我是隔壁老王呀 于 2015-6-22 10:46 编辑

因为
public void method(Animal a) {
    if (a instanceof Dog)
        Dog d = (Dog) a;
}
这里面的 Dog d = (Dog) a;这句在编译时候是这样的
{
    Dog d;
    d = (Dog) a;
}
Dog d = (Dog) a;在编译器编译时其实分解为两条语句,你不加大括号,相当于只执行第一条语句Dog  d; 这是一条声明语句,且是局部变量声明语句,而对于if语句则需要是执行语句,不能只是声明语句,这是第一个错误。而且局部变量有其作用范围,当执行完Dog d;时,局部变量d的作用范围已经结束,后面再使用d就会报错,因为在内存中并么有d的空间,这是第二个错误。
可以这样修改:
...
Dog d;
if(a instanceof Dog)
    d= (Dog) a;
...
这样编译器没有错误。因为此时d的作用范围包含if的执行语句,且if后面的语句就是d= (Dog) a;是一条明确的执行语句。所以就不会报错。    而你在if后加{}也是一样的道理,既扩大了d的作用范围,又有执行语句可以执行,所以编译器就能通过。
   

作者: lvzhfeng    时间: 2015-6-22 07:24
试了一下, 这样不报错。     
            if (a instanceof Dog)
                        {
                                Dog d;
                                d = (Dog)a;
                                d.eat();
                        }
因为此时局部变量d的作用域在大括号里面
单独写了一个Test类,实验了一下,也是不行。
  1. class Test
  2. {
  3.         public static void method(Person p)
  4.         {
  5.                 if(p instanceof Student)
  6.                         Student stu = (Student)p;

  7.         }
  8. }

  9. class Person
  10. {
  11.         private String name;
  12.         private int age;
  13.         Person(String name,int age)
  14.         {
  15.                 this.name = name;
  16.                 this.age = age;
  17.         }
  18.         public void method()
  19.         {
  20.                 System.out.println("name="+name+"age="+age);
  21.         }
  22. }

  23. class Student extends Person
  24. {
  25.         Student(String name,int age)
  26.         {
  27.                 super(name,age);
  28.         }
  29.         public void study()
  30.         {
  31.                 System.out.println("study");
  32.         }

  33. }




  34. class Demo
  35. {
  36.         public static void main(String[] args)
  37.         {
  38.                 Student p = new Student("Jack",20);
  39.                 new Test().method(p);
  40.         }
  41. }
复制代码


我考虑是这样的Dog d = (Dog) a;并非是两个语句,但是此时声明的d是局部变量,如果只有一条声明,那么这条语句就没有意义,只会制造内存垃圾。但是加上括号,系统默认你将使用多行语句,d的作用域变大,而可能不仅仅只是声明。
一句话:不加括号,声明d一定没有意义。加上括号,d可能在该作用域中用到。
所以一定没意义的,系统有义务报错;可能有意义的,系统不会报错(尽管声明的d真没什么用)
作者: 改变    时间: 2015-6-22 10:04
涨姿势了。。。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2