1、下面程序的输出结果是()
public class Test { public static void main(String[] args) { int j = 0 ; for(int i = 0 ; i < 100 ; i++){ j = j++ ; } System.out.println(j); } }
A. 0 B.99 C.100 D.101
解析:因为Java采用了中间缓存变量的机制,所以, j = j++可以换成 temp = j ; j = j + 1 ; j = temp ;所以结果为0.
关于中间缓存变量机制可以参考文章:http://blog.csdn.net/waycaiqi/article/details/43486249
2、以下程序错误的是()
A. short s = 1; s = s + 1 ; B. short s = 1 ; s += 1 ; C. short s = 1 ; s = 1 + 1 ;
解析:使用+=、-=、*=、/=、%=等赋值运算符对基本类型运算时,运算符右边的数字将首先被强制转换成与左边数值相同的数据类型,然后在进行运算,且运算结果与运算符左边的数值类型相同,所以选项B正确。对于选项C,1+1是一个可以确定的常量,“+”在编译时就被执行了,而不是在程序运行的时候执行,所以效果等同于s = 2 ; 的赋值操作,所以也正确。而A选项中的 s+1执行后的结果为int型,所以不能赋值给s。故错误的A
3、以下代码的输出结果是()
public class Test { public static void main(String[] args) { int a = 5 ; System.out.println("value is " + ((a < 5) ? 10.9 : 9)); char ch = 'x' ; int i = 10 ; System.out.println(false ? i : ch ); System.out.println(false ? 10 : ch ); } }
解析:Java编程规范中提到,对于三目运算符?:而言,当后两个表达式的数据类型不一致时,系统会自动将两个表达式的类型转化一致,所以第一个输出结果为9.0而不是9,第二个输出结果为120。此外,Java编程规范中还提到,当后两个表达式有一个是常量表达式(本题是10)时,另外一个类型是T(本题是char)时,而常量表达式可以被T表示时,输出结果是T类型。所以第三个输出的是x而不是120。所以,最终的结果是9.0 120 x 。
4、下面程序的输出结果是()
public class Test { public static void main(String[] args) { int num = 32 ; System.out.println(num >> 32); } }
A. 32 B. 16 C. 1 D. 0
解析: 移位操作符右边的参数首先要对字长进行取模运算,并且移位是对二进制位进行操作,而二进制中8位是一个循环。本题中num为int类型,字长是32,所以num>>32等于num>>0,而num>>33等于num>>1.所以答案为A。
注意:在移位运算时,byte、short和char类型移位后的结果会变成int类型,对于byte、short、char和int进行移位时,规定实际移动的次数是移动次数和32的余数,也就是移位33次和移位1次得到的结果相同。移动long型的数值时,规定实际移动的次数是移动次数和64的余数,也就是移动66次和移动2次得到的结果相同。
5、当编译下面代码会出现什么情况()
public class Test { private int count ; //构造函数 Test(int count){ this.count = count ; } public static void main(String[] args) { Test t = new Test(99) ; System.out.println(t.count); } }
A. 编译时错误,count变量定义的是私有变量
B. 编译时错误,当System.out.println被调用时t没有被初始化
C. 编译和执行时没有输出结果
D. 编译运行后输出结果99
解析:事实上,变量count被定义为私有变量,并不能阻止构造器对其进行初始化,所以count成功被初始化为99,故答案为D
注意,count变量被私有化之后,理论上是不能被访问的。但是该main方法是在本类的内部,所以可以直接访问。如果在另一个类中这样访问Test对象的count变量,是不会成功的,例如下面的代码会在第18行提示访问错误。
1 public class Test { 2 3 private int count ; 4 //构造函数 5 Test(int count){ 6 this.count = count ; 7 } 8 9 public static void main(String[] args) { 10 Test t = new Test(99) ; 11 System.out.println(t.count); 12 } 13 } 14 15 class T{ 16 public static void say(){ 17 Test t = new Test(55) ; 18 //System.out.println(t.count) ; //无法编译通过,提示有错误 19 } 20 }
6: 8、16、64都是2的阶次方数,用Java编写程序来判断一个整数是否是2的阶次方,并说明那个方法更好?
解析:
思路1:不断除以2,并判断是否整除。这是最先想到的方法
public boolean judge(int n){ int num = n ; if(n < 0){ return false ; } //因为1为2的阶次方数,所以不用判断,当大于2时进行判断 while(num >= 2){ if(num%2 == 1){ return false ; } num = num/2 ; } return true ; }
思路2:如果一个数是2的阶次方数,那么其二进制的首位为1,其他为均为0。eg:8的二进制表示为100,64表示为1000000等,若将该数减1,则对应的二进制首位为哦,其它位均为1,所以有n & (n-1)的结果为0。所以采用这种方法可以简单快速地进行判断。简单,粗暴,高效。
public boolean judge2(int n){ if((n & (n-1)) == 0){ return true ; }else{ return false ; } }
7、下面程序输出结果是什么?
1 import java.net.URL; 2 import java.util.HashSet; 3 import java.util.Set; 4 5 public class Test { 6 7 private static final String [] URLNAMES = { 8 //IP地址为202.108.33.94 9 "http://www.sina.com", 10 //IP地址为124.115.173.252 11 "http://www.nwu.edu.cn", 12 //IP地址为208.97.154.9 13 "http://javapuzzlers.com", 14 //IP地址为64.233.189.147 15 "http://www.google.com", 16 //IP地址为208.97.154.9 17 "http://Javapuzzlers.com", 18 //IP地址为208.97.154.9 19 "http://apache2-snort.skybar.dreamhost.com", 20 }; 21 22 public static void main(String[] args) throws Exception { 23 Set<URL> favorites = new HashSet<URL>() ; 24 for(String s : URLNAMES){ 25 favorites.add(new URL(s)) ; 26 } 27 28 System.out.println(favorites.size()); 29 } 30 }
A. 一定是4 B. 一定是5 C. 一定是6 D.以上答案都不对
解析:本题在联网状态下会输出4,这是由于URL的equals比对方式,根据equals的文档说明,如果两个主机名可以解析为同一个IP地址,则认为两个主机相同(即使主机名不相同);如果由一个主机名无法解析,但两个主机名相等(不区分大小写)或两个主机名都为null,则也认为这两个主机相等。上面有三个IP都是208.97.154.9,而Set集合不允许有重复元素出现,所以在联网情况下输出为4
如果是在断网状态下,这些都无法解析为IP地址,这时就要判断URL的名字,仅认为名字相同的才是相同的URL,前面说过URL的判断不区分大小写,而有两个在不区分大小写的情况下是相同的,所以输出结果是5.
所以最后的答案是D