switch局部变量的问题,求高人解答.

祥林会跟你远走高飞 发布于 2013/01/28 13:47
阅读 809
收藏 0

云原生2.0展望丨从“小众”到“首选”,推动云原生产业落地华为云作用几何?>>>

public void test(int temp){

    switch(temp){

        case 1:    

                String txt = "";

                txt = do something...;

                break;

    case 2:

                txt = do something...;

                break;

        default:

                do something...;

                break;

    }

}

说明:1,调用此方法两次,第一次走case1,第二次走case2。

提问:1,会出错?,编译时,还是执行时,并说出具体原因。

        2,不会出错?,那么第二次 txt这个变量声明了没有?在内存哪里啊。

加载中
0
leo108
leo108

按照你的描述,我猜测java的机制可能和js的有点类似,会自动把变量申明提到最前。

你的代码等效于

public void test(int temp){
    String txt; //注意此行
    switch(temp){
        case 1:    
            txt = ""; //还有这里
            txt = do something...;
            break;
        case 2:
            txt = do something...;
            break;
        default:
            do something...;
        break;
    }
}
对JAVA不是很了解,不一定对哈
祥林会跟你远走高飞
祥林会跟你远走高飞
你的这种说法我也很同意,事实上经过测试后也确实如您所说。是这样的,下面一哥们给出了我编译后的代码,我先看下在跟您说下。
0
寂寞沙洲
寂寞沙洲
人脑又不是编译器 自己断点试试不就行了?说不定编译器直接报错
祥林会跟你远走高飞
祥林会跟你远走高飞
我已断点调试,但是并没报错。我就想问一下,为什么在第二次运行此方法的时候txt是局部变量未声明,没有开辟空间,却能使用。再编译时,为什么没有报错。
0
excepiton
excepiton

应该是2,txt在Switch代码块里面定义了。

case 1:{

}

case 2:{

}

这样写的时候可能就会编译失败

excepiton
excepiton
回复 @王鹏1989 : 你没理解代码块的含义
祥林会跟你远走高飞
祥林会跟你远走高飞
没有啊 这样声明,编译时并没有报错,执行时也没有报错。按道理来讲,在方法调用的第一次时 执行case1声明了此局部变量,这样没错。方法结束后局部变量弹栈出去,第二次执行case2并没有声明此局部变量,也就是说在内存中没有为它开辟空间,但是没有报错。这一点是我比较纳闷的。。。
0
leo108
leo108

default能写在switch的大括号外面?

在c++里面,理论上是不允许在case里面定义变量的

祥林会跟你远走高飞
祥林会跟你远走高飞
哦,不要意思上面的 default是在switch里面,我改了下。 我是用的java编译器。事实上这段代码是可以执行的,不管是在编译时还是执行时都不会报错。但是第二次执行此方法走case2时并没有定义txt变量 也就是并没有在内存中开辟空间,但是可以使用。我就是想问下,他执行.class文件时是怎么找到这个变量的txt,为什么不会报错。
0
祥林会跟你远走高飞
祥林会跟你远走高飞
希望高手给讲讲jvm编译此class类后的细节问题,和执行方法的顺序问题。
0
excepiton
excepiton
这个编译后的代码,你可以看下。看了之后应该就能理解了。
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_2
   1:   invokestatic    #2; //Method test:(I)V
   4:   iconst_2
   5:   invokestatic    #2; //Method test:(I)V
   8:   return

public static void test(int);
  Code:
   0:   iload_0
   1:   lookupswitch{ //2
                1: 28;
                2: 37;
                default: 43 }
   28:  ldc     #3; //String
   30:  astore_1
   31:  ldc     #4; //String 1
   33:  astore_1
   34:  goto    43
   37:  ldc     #5; //String 2
   39:  astore_1
   40:  goto    43
   43:  return

}


----------------


public class Test{
	public static void main(String[] args){
		test(2);
		test(2);
	}
	public static void test(int temp){
    switch(temp){
        case 1:    
                String txt = "";
                txt = "1";
                break;
    case 2:
                txt = "2";
                break;
   default:
              break;
    }
}
}
Seventh7
Seventh7
javap -v your.class
祥林会跟你远走高飞
祥林会跟你远走高飞
大哥 您这个两次都走的 case2啊,我的意思是先走case1 再走case2.另外您用的什么软件看的上面的编译的文件啊。
0
Seventh7
Seventh7
这里有篇文章,可以看看http://blog.sina.com.cn/s/blog_474928c901014684.html
0
祥林会跟你远走高飞
祥林会跟你远走高飞

引用来自“Seventh7”的答案

这里有篇文章,可以看看http://blog.sina.com.cn/s/blog_474928c901014684.html
我仔细了看了一下您的分享,给我的理解是这样的。我们可以再case里面声明变量,但是最好加上{},避免不同case之间重复的声明变量,如果没有{},多个case共享此变量,并把此变量提前至swith前,并且仅仅是变量的声明是这样的,变量的赋值在哪个case还是再哪里。。。那么现在我的问题是:这种情况的出现应该是java的机制问题,而并不是switch的机制问题?因为提前声明的变量肯定是在switch外,但是真的有这种执行方法变量提前的机制么?如果是这样,先声明再使用的规则不是一句空话么? 是不是只有在包含switch的方法这种方法下才会有这种特权。
返回顶部
顶部