java中的switchswitch问题

在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
标签:至少1个,最多5个
这些都是一些小问题,但是有助于理解输入输出流。InputStreamReader 中的一个 read()是每次只会从磁盘里面读取一个字节。它会非常频繁的访问磁盘。(想一想,每次只从磁盘读一个字节)InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。 每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。 为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:
BufferedReader in
= new BufferedReader(new InputStreamReader
import java.io.*;
import java.io.DataInputS
public static void main(String[] args) throws
Exception {
BufferedReader
reader= new BufferedReader(new InputStreamReader(new FileInputStream(new File("text.txt"))));
String line=
while((line=reader.readLine())!=null){
s=line.split("\\s+");
for ( String single:s ) {
System.out.println(single);
(System.in));\s匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格
Java的重定向JAVA支持标准的输出输入重定向。
public static void main(String[] args) throws
Exception {
System.out.println("Hello World!");
编译以后,直接使用java
Main &test.txt进行输出重定向
使用输入重定向:
public static void main(String[] args) throws
Exception {
Scanner sc=new Scanner(System.in);
while(sc.hasNextLine())
System.out.println(sc.nextLine());
Main&text.
0 收藏&&|&&1
你可能感兴趣的文章
3 收藏,1.9k
分享到微博?
我要该,理由是:博客分类:
switch是控制选择的一种方式,编译器生成代码时可以对这种结构进行特定的优化,从而产生效率比较高的代码。在java中,编译器根据分支的情况,分别产生tableswitch,lookupswitch两中情况,其中tableswitch适用于分支比较集中的情况,而lookupswitch适用与分支比较稀疏的情况。不过怎么算稀疏,怎么算集中就是编译器的决策问题了,这里不做深入的分析。
简单的找几个例子。
public class Test {
public static void main(String[] args) {
int i = 3;
switch (i) {
System.out.println("0");
System.out.println("1");
System.out.println("3");
System.out.println("5");
System.out.println("10");
System.out.println("13");
System.out.println("14");
System.out.println("default");
反汇编代码可以发现其跳转表的结构:
0: iconst_3
1: istore_1
2: iload_1
3: tableswitch{ //0 to 14
default: 153 }
76: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
79: ldc #3; //String 0
81: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
84: goto 161
87: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
90: ldc #5; //String 1
92: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
95: goto 161
98: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
101: ldc #6; //String 3
103: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
106: goto 161
109: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
112: ldc #7; //String 5
114: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
117: goto 161
120: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
123: ldc #8; //String 10
125: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
128: goto 161
131: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
134: ldc #9; //String 13
136: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
139: goto 161
142: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
145: ldc #10; //String 14
147: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
150: goto 161
153: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
156: ldc #11; //String default
158: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
161: return
其中的 3:tableswitch{ //0 to 140: 76;1: 87;2: 153;3: 98;4: 153;5: 109;6: 153;7: 153;8: 153;9: 153;10: 120;11: 153;12: 153;13: 131;14: 142;default: 153 }就是跳转表,对于tableswitch指令,这里high为14,low为0,表中共有high-low+1个分支项,当jvm遇到tableswitch指令时,它会检测switch(key)中的key值是否在low~high之间,如果不是,直接执行default部分,如果在这个范围之内,它使用key-low这个项指定的地点跳转。可见,tableswitch的效率是非常高的。
public class Test2 {
public static void main(String[] args) {
int i = 3;
switch (i) {
System.out.println("3");
System.out.println("20");
System.out.println("50");
System.out.println("100");
反汇编代码:
0: iconst_3
1: istore_1
2: iload_1
3: lookupswitch{ //4
default: 85 }
44: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
47: ldc #3; //String 3
49: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
52: goto 85
55: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
58: ldc #5; //String 20
60: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
63: goto 85
66: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
69: ldc #6; //String 50
71: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
74: goto 85
77: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintS
80: ldc #7; //String 100
82: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/S)V
85: return
这里使用的是lookupswitch:
3:lookupswitch{ //43: 44;20: 55;50: 66;100: 77;default: 85 }这种情况下,必须依次检测每一个项目看是否和switch(key) 中的key匹配,如果遇到匹配的直接跳转,如果遇到比key值大的,执行default,因为3,20,50,100这些项目是按照升序排列的,所以遇到比 key值大的case值后就可以确定后面没有符合条件的值了。另外一点,升序排列也允许jvm实现这条指令时进行优化,比如采用二分搜索的方式取代线性扫描等。
最后,记住jvm规范中的几句话:
  Compilation of switch statements uses the tableswitch and lookupswitch instructions. The tableswitch instruction is used when the cases of the switch can be efficiently represented as indices into a table of target offsets. The default target of the switch is used if the value of the expression of the switch falls outside the range of valid indices.
  Where the cases of the switch are sparse, the table representation of the tableswitch instruction becomes inefficient in terms of space. The lookupswitch instruction may be used instead.
  The Java virtual machine specifies that the table of the lookupswitch instruction must be sorted by key so that implementations may use searches more efficient than a linear scan. Even so, the lookupswitch instruction must search its keys for a match rather than simply perform a bounds check and index into a table like tableswitch. Thus, a tableswitch instruction is probably more efficient than a lookupswitch where space considerations permit a choice.
浏览: 80178 次
来自: 北京
&div class=&quote_title ...
然鹅。。jdk1.8已经把这货移到了heap区?只有把-Xmx ...
还有你是基于jdk那个版本
我想问下,你这个方法跑啦多长时间
hsbljyy 写道看来真的有很多谬误啊!当变量在-128~1 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'switch case语句里面不能定义对象,有语法错误,除非加一个花括号
最近发现一个问题呢 发现在switch的case里面不能去定义对象了,一定义对象就会报错了
仔细了解了一下在C或者C++中,只要是在任何一对花括号 &{ }&中定义的对象,那么该对象的作用域就局限在这对花括号里面,上面的代码的错误就出现在这儿了。
switch (i) {&
&&&&&&& case 0:&
&&&&&&&&&&& UIViewController *view = [[UIViewController alloc]init];&
&&&&&&&&&&& //。。。。code&&
&&&&&&&&&&&&
&&&&&&& case 1:&
&&&&&&&&&&& //此处如果在使用view的话就会出错了。。。&&
&&&&&&&&&&&&
&&&&&&& default:&
&&&&&&&&&&&&
switch (i) {
&&&&&&& case 0:
&&&&&&&&&&& UIViewController *view = [[UIViewController alloc]init];
&&&&&&&&&&& //。。。。code
&&&&&&&&&&&
&&&&&&& case 1:
&&&&&&&&&&& //此处如果在使用view的话就会出错了。。。
&&&&&&&&&&&
&&&&&&& default:
&&&&&&&&&&&
1. view的作用域应该是整个switch语句。 也就是不管case 0 还是case 1,都应该起作用的。
2.加入此时的i 为1,那么程序会跳过case 0,直接执行case 1。 假如你又在case 1中调用对象view,那么此时的view是没有初始化 没有声明的,自然而然的出错了。
所以这是一个语法错误
3.就是出于这种原因& 才有了我们看到的结果,那么知道了原因 就要解决问题了, 既然view的作用域只想在case 0里面 那么我们加个花括号不就好了吗
此时的代码改为以下
switch (i) {&
&&&&&&& case 0:&
&&&&&&& {&
&&&&&&&&&&& UIViewController *view = [[UIViewController alloc]init];&
&&&&&&&&&&& //。。。。code&&
&&&&&&& }&
&&&&&&&&&&&&
&&&&&&& case 1:&
&&&&&&&&&&& //此处如果在使用view的话就会出错了。。。&&
&&&&&&&&&&&&
&&&&&&& default:&
&&&&&&&&&&&&
switch (i) {
&&&&&&& case 0:
&&&&&&&&&&& UIViewController *view = [[UIViewController alloc]init];
&&&&&&&&&&& //。。。。code
&&&&&&&&&&&
&&&&&&& case 1:
&&&&&&&&&&& //此处如果在使用view的话就会出错了。。。
&&&&&&&&&&&
&&&&&&& default:
&&&&&&&&&&&
这样就没问题了,或者把view声明在swith语句的前面就OK了。2被浏览1475分享邀请回答0添加评论分享收藏感谢收起0添加评论分享收藏感谢收起

我要回帖

更多关于 java中switch和if 的文章

 

随机推荐