Java基础知识点

来源:互联网 发布:新大洋知豆电动汽车 编辑:程序博客网 时间:2024/05/20 01:34

今天我为大家带来的是几个常见的Java细节问题,面试时很容易出现。

1、switch语句能否作用在byte上,能否作用在long上,能否作用在String上?
在switch(expr1)中,expr1只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是int基本类型或Integer包装类型,由于,byte,short,char都可以隐含转换为int,所以,这些类型以及这些类型的包装类型也是可以的。显然,long和String类型都不符合switch的语法规定,并且不能被隐式转换成int类型,所以,它们不能作用于swtich语句中。

但是由于JDK的优化,目前已经支持使用String

2、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
对于short s1 = 1; s1 = s1 + 1;由于s1+1运算时会自动提升表达式的类型,所以结果是int型,再赋值给short类型s1时,编译器将报告需要强制转换类型的错误。
而对于后者,s1+=1等价于s1=(short)(s1+1)因此是不会报错的,也就是说,编译器对+=进行了优化。

3、char型变量中能不能存贮一个中文汉字?为什么?
char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中当然可以存储汉字啦。不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。补充说明:unicode编码占用两个字节,所以,char类型的变量也是占用两个字节。

4、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。例如,对于如下语句:
final StringBuffer buf=new StringBuffer(“hello”);
buf.append(“world”)是可以的,但是
buf=new StringBuffer(“hi”)会报错。

5、"=="和equals方法究竟有什么区别?
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同
equals变量用于判断两个引用所指向的内存中的对象是否相等,而这种相等是利用hashcode计算得到的。
Integeri1=newInteger(1);
Integeri2=newInteger(1);
int i3=1;
System.out.println(i1==i2);//false
System.out.println(i1.equals(i2))//true
System.out.println(i1.==i3)//true  此时将Integer拆箱为int

Stringa=“A";
Stringb=newString("A");System.out.println(a==b);//false

Stringa="A";
Stringc="A";
System.out.println(a==c);//true这是一个特例,编译器对常量赋值进行了优化,a与c所指向的内存都是一样的
这种简写形式,头一个String a="A"; ,会在常量池中创建一个对象“A”,而String b="A";在常量池中已经有“A”这个对象了,所以不会创建,所以都指的是同一个“A”

6、抽象类是否可继承具体类(concrete class)?抽象类中是否可以有静态的main方法?
抽象类可以继承具体类。抽象类中也可以有静态的main方法。

7、interface中得成员变量和成员方法
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。

8、非静态内部类中可以定义静态变量吗?
不能,非静态内部类只有在实例化外部类后才能实例化,自然无法定义静态变量
但是注意,在静态内部类中可以定义静态常量

9、内部类可以引用它的包含类的成员吗?有没有什么限制?
完全可以。如果不是静态内部类,那没有什么限制!
如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员。

10、下面这条语句一共创建了多少个对象:
String s="a"+"b"+"c"+"d";
答:对于如下代码:
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");

第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。

题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个”abcd”的字符串,所以,上面的代码应该只创建了一个String对象。写如下两行代码,

String s ="a" + "b" + "c" + "d";
System.out.println(s== "abcd");
最终打印的结果应该为true。

11、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
事实上,程序在执行到return时,返回值已经被确定,但是由于finally模块,因此,程序在return之前会执行finally中的代码,不过,finally模块无法改变return的结果值。

12、运行时异常与一般异常有何异同?
一般异常必须声明抛出并做处理,而运行时异常不需要声明并捕获。

13、Error与Exception的异同
两者都继承了Throwable接口,区别如下:
       Exception:

1.可以是可被控制(checked) 或不可控制的(unchecked)。

2.表示一个由程序员导致的错误。

3.应该在应用程序级被处理。


Error:
1.总是不可控制的(unchecked)。
2.经常用来用于表示系统错误或低层资源的错误。
3.如何可能的话,应该在系统级被捕捉。
        4.  一般无法恢复

14、sleep()和 wait()有什么区别?
sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。对于wait的讲解一定要配合例子代码来说明,才显得自己真明白。






0 0
原创粉丝点击