说明:本面试题大多都是根据《Java面试问题集》、《Java程序员面试宝典》、《程序员面试宝典》等书籍概括精选而来,其中也补充了一些自己在找工作的过程中遇到的面试题,虽然不能遍及Java的所有知识点,但绝对都是面试会问到的高频知识点。
1.Java中的作用域public,private,protected,以及不写作用域(default)时有什么区别?
Java中有四种作用域,按照作用域范围由大到小排列一次是:public , protected , default , private。
private表示只能在当前类中使用;
default表示只能在当前类或者是同一个包下面使用;
protected表示可以在当前类,同一个包下,当前类的子类中使用;
public表示除了上面的情况外,还可以被其它包中的类使用。
2.匿名内部类是否可以继承其它类,是否可以实现其它接口?
首先需要搞清楚内部类和匿名内部类的概念和特点,可以参考以下链接:
http://android.blog.51cto.com/268543/384844/
http://www.cnblogs.com/o-andy-o/archive/2012/04/07/2435825.html
内部类分为三种:成员内部类,局部内部类(又称方法内部类),匿名内部类。(这里不把静态嵌套类归类于内部类,在后面会单独讲到)
本题问的是匿名内部类,那么我们来看一段代码:
public class Car {
public void drive() {
System.out.println("drive a car!");
}
}
public class Outer {
public static void main(String[] args) {
Car car = new Car(){
//要使用匿名内部类必须先定义该类(接口)
//此处匿名内部类会默认继承已经定义的类(Car)
public void drive() {
System.out.println("drive another car!");
}
};
car.drive();
}
}
其中,new Car()就是一个匿名内部类,继承了它的父类Car。
所以,本题答案是匿名内部类可以而且是必须继承一个父类或者实现一个接口。
3.静态嵌套类和内部类的区别。
首先,我们看一下静态嵌套类的例子:
public class Outer {
public static void main(String[] args) {
Outer.Inner inner = new Inner();
Outer.Inner.print();
}
public static class Inner {
public static void print() {
}
}
}
该静态嵌套内部类可以像其它静态成员一样,没有外部类对象时也能够通过外部类的类名访问它。但是,它不能访问外部类的成员和方法,因为无法知道外部类是否生成对象,只有外部类实例化了对象,外部类才会有成员和方法。
而内部类必须要实例化外部类的对象才能被访问,而且,内部类是可以通过Outer.this来获取外部类对象,从而访问外部类的成员和方法。
4.&和&&的区别。
&是位运算符,&&是逻辑运算符。位运算2&3=2是因为转换为二进制为10&11=10,10是2的二进制表示。逻辑运算true&&false=false。在Java中&也可也用来做逻辑运算true&false=false。
它们的区别在于:在做逻辑运算的时候,&&具有短路的功能,而&不具备。下面举例说明。
public class TestAnd {
//类变量,不会被初始化,值为null
public static String str1;
public static String str2;
public static void main(String[] args) {
if(str1 != null && str2.equals(“”)) {
...
} else {
...
}
}
}
当使用&&时,首先判断str1 != null 为false,所以短路,不会执行后面的操作。
当使用&时,虽然前面为false,但是仍然执行后面的判断str2.equals("")
,此时会抛出空指针异常。
5.Java中Collection和Collections的区别。
Collection是Java集合框架中最上级的接口之一。Collection的实现类主要有List,Queue,Set等等。
Colelctions是Collection集合框架的一个帮助类(工具类),它直接继承Object,不属于集合框架,主要提供一系列的静态方法对Collection集合进行各种操作。
6.String s = new String(“abc”);这句话创建了几个对象?
两个。new String(“abc”)是一个字符串对象;s是一个字符串对象的引用对象。
7.Math.round(11.5),Math.round(-11.5),Math.floor(11.7),Math.floor(-11.7)的值各是多少?
Math.round(a)是四舍五入;Math.floor(a)是返回小于等于a的最大的double值(即向下取整)。
所以答案为:12,-11,11,-12
另外:还有一个ceil方法是向上取整。
8.short s1 = 1;s1=s1+1和short s1 = 1;s1+=1;有什么区别?
s1 + 1会自动向上转型成为int,将int赋给short会编译报错,需要强制类型转换:s1 = (short)s1 + 1;
对于s1 += 1;编译器会自动将+=后面的操作数强制转换成前面变量的类型,然后在变量所在的内存区上直接根据右边的操作数修改左边变量内存存储的二进制数值,属于位运算,能正确通过编译。
另外,后一种方式属于位运算,效率比前者要高。
9.Java中有没有goto语句?
Java关键字:共51个。
Java保留字:共14个,表示现有的Java版本尚未使用,但以后版本可能会作为关键字使用。
其中,goto就是Java的保留字。
10.数组有没有length()这个方法,String有没有length()这个方法?
数组没有length()方法,但是有length属性。String有length()方法。
补充:集合框架测量长度的方法是size()。
11.简述Overload(重载)和Override(重写)的区别。
重载和重写是Java多态中的内容。重写是父类与子类之间多态性的一种表现,重载是一个类中多态性的一种表现。
重载是在一个类中定义多个同名的方法,但是允许这些方法的返回值类型,参数列表,访问修饰符,异常等不同。换言之,除了方法名之外,其它都可以不同。
重写是因为子类想对父类中某个方法的功能做修改,而不再增加一个新的方法。重写的要求比较严格,返回值类型,方法名称,参数列表必须严格一致,访问修饰符必须大于等于被重写的方法,比如,父类的访问修饰符是protected,子类重写方法的修饰符可以是protected或者是public。
值得一提的是,如果父类的方法是private,那么子类中重写的这个方法就不能算是重写,相当于子类中增加了一个全新的方法。重写的方法不能抛出新的异常类型,但是允许是原异常类型的子类异常。
12.集合框架Set中的元素能否重复?用什么方法来判断集合中的元素是否重复?用==还是equals()?它们有什么区别?
Set是不能存放重复元素的,即使是null,在Set中也只能存放一个。Set中元素的顺序和元素的插入顺序无关,是由Set内部的排序机制自行排序的。
再来说说==和equals()的区别:
当比较双方是基本数据类型的时候,应该使用==来进行比较,比较的是它们的值。
当比较双方是复合数据类型的时候,可以使用==也可以使用equals()来进行比较。
首先,当使用==时,比较的是它们在内存中的存放地址。当使用equals()方法时,默认比较的是两者的内存地址,和==一样。这是因为在Object这个类中定义了这个比较内存地址的equals()方法。但在一些类库中这个equals()方法被重写了,比如String,Integer和Date等,在这类中equals()就有了它们自己的实现,比较的就不一定是两者的内存地址了。如果想让两个复合数据类型的equals方法比较的是它们的值而不是地址,需要重写hashCode和equals方法。
13.给我一个你最常见到的runtime exception
ArithmeticException,
BufferOverFlowException,
ClassCastException,
IllegalArgumentException,
NullPointerException…
Exception:http://blog.csdn.net/hguisu/article/details/6155636
14.Error和Exception的区别。
Error和Exception都是Throwable的子类。
Error是程序无法处理的错误,表示运行应用程序中较严重的问题,比如内存溢出。
Exception是程序本身可以处理的异常,表示一种设计或者实现上的问题。
详见http://blog.csdn.net/hguisu/article/details/6155636
15.List,Set,Map是否继承自Collection接口?
List和Set是,Map不是。
可以参考Java集合框架的继承图。
http://blog.csdn.net/zsw101259/article/details/7570033
16.abstract class(抽象类)和interface(接口)有什么区别?
说到抽象类和接口,不得不先说一下抽象方法,有关抽象方法,抽象类和接口的知识详细参见:
http://www.cnblogs.com/dolphin0520/p/3811437.html
这里补充强调一下区别:
a)抽象类可以有构造方法,接口中不能有构造方法。(虽然抽象类不能创建实例对象)
b)抽象类的成员变量可以是各种类型的,接口中的成员变量是public static final 类型的。
c)抽象类可以有抽象方法,也可以有具体实现的方法;接口只能有抽象方法。
d)抽象类的抽象方法可以是public和protected,接口的抽象方法只能是public abstract。
e)抽象类中可以有静态方法和静态代码块,接口中不行。
f)单继承,多实现。
g)从使用方面来说,继承是为了代码的复用,接口是为了系统的逻辑设计。
17.抽象方法是否可以用static,native,synchronized来修饰吗?
在类中,没有方法体的方法就是抽象方法。
构造方法,静态方法,私有方法,final方法不能被声明为抽象方法,抽象方法也不能使用native,static,final,private,protected,synchronized来修饰。
原因:
抽象方法是需要在子类中实现的,本身没有实现体,通过抽象类名来调用这个没有实现体的抽象静态方法完全没有意义,所以抽象方法不能是static。
虽然native修饰的方法不能有实现体但却表示该方法要用另外一种编程语言实现,不存在被子类实现的问题,所以native方法不能是abstract的。因此,抽象方法不能是native。
一个抽象方法没有实现体,需要synchronized有什么用,也不行。
18.接口是否可以继承接口,抽象类是否可以实现接口,抽象类是否可以继承实体类?抽象类中是否可以有静态的main方法?
接口可以继承接口,抽象类可以实现接口,但接口不能继承抽象类,抽象类也可以继承实体类,但前提是实体类必须有明确的构造函数(或者说,实体类中必须有子类可以访问的构造函数)。抽象类中可以有静态的main方法这个详见:
http://blog.sina.com.cn/s/blog_7042a6c101013ung.html
tips:抽象类和具体类的区别:抽象类用abstract修饰,抽象类不能被实例化,抽象类中允许有抽象方法。
19.构造器(构造函数)能否被重写?
一个类的构造函数不能被重写,但是可以重载。
20.是否可以继承String类?
查阅JDK帮助文档,可以看到String类的定义声明:
public final class String extends Object implements Serializable, Comparable
由于是final类型的,所以,String类是不能被继承的。
建议:String类的所有方法都要看一下,考的很多。
21.try{}里面有一个return语句,那么紧跟在这个try后面的finally{}里的代码会不会被执行,什么时候执行。
会执行,在try{}里面的return语句返回之前执行。
重要示例:
http://blog.csdn.net/u012050416/article/details/50781426
22.用最有效率的方法算出2*8
最有效率的就是位运算,2<<3就可以了。
23.两个对象值相等(x.equals(y) == true),但却可以有不同的hash code,这句话对吗?
首先需要了解hashcode的作用:
http://blog.csdn.net/fenglibing/article/details/8905007
如果两个对象相同,那么这两个对象的hashcode一定相同;但是如果两个对象的hashcode相同,并不一定表示这两个对象就相同。
所以这句话是错的。
24.当一个对象被当做参数传递给一个方法后,此方法可以改变这个对象的属性,并可以返回变化后的结果,那么这算是按值传递还是引用传递?
首先要搞清楚Java中的按值传递和引用传递分别是什么意思:
http://blog.csdn.net/zzp_403184692/article/details/8184751
首先要弄清楚题目中说的对象是基本类型还是复合数据类型的对象,由上面文章可知,如果为基本类型(及其包装类)或者是String,那就是按值传递,因为参数传递过去的是值的拷贝;如果是复合数据类型的对象(除了基本数据类型及其包装类和String),那么传递的参数是这个对象的引用,就算是引用传递,比如StringBuilder,StringBuffer等等。
25.switch是否能作用在byte,long,String上?
jdk1.6以前可以支持byte,char,short,int,enum。要注意,没有long
jdk1.7新增加了对String的支持。
26.char中可以存放一个中文汉字吗?
一个中文汉字需要两个字节才能存放,只要我们记住Java中基本数据类型所占的字节数就可以了。
基本类型 | 大小 |
---|---|
char | 2 |
byte | 1 |
short | 2 |
int | 4 |
long | 8 |
float | 4 |
double | 8 |
所以本体的答案是可以。另外,如果某个特殊的汉字没有被包含在unicode中,那么char就不能表示出这个汉字。
参考资料:字符编码方式
27.GC是什么,为什么要有GC?
GC是垃圾收集的意思(GabageCollection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。
28.float f = 3.4这样书写是否正确?
不正确,在Java中,小数默认是采用double类型的,此处3.4是double类型的,这句话会出现编译错误,应该强制类型转换:
float f = (float)3.4
或者这样写:
float f = 3.4f
29.String和StringBuffer的区别
一个String对象创建以后,它在内存中的内容是不可变的,之所以有
String s = "abc";
s = s + "d";
这是因为创建了两个String对象,分别是“abc”和“abcd”,而s的引用指向了“abcd”。
StringBuffer的内容是可以改变的,而且在更改的过程中只创建一个对象。
String类重写了equals方法和hashCode方法,StringBuffer类却没有,所以:
new String(“abc”).equals(new String(“abc”))
结果为true,
new StringBuffer(“abc”).equals(new StringBuffer(“abc”))
的结果为false。
当需要对某个字符串经常修改时,尽量采用StringBuffer类型,最后如果想得到String类型,可以调用StringBuffer的toString()方法。
Tips:StringBuilder和StringBuffer都是可变的,区别在于,StringBuilder不是线程安全的,StringBuffer是线程安全的。效率上,前者优于后者。
30.说一说final,finally和finalize的区别
final和finally都是Java的关键字,finalize是一个方法名。
final是修饰符,可以用来修饰类,表示该类不能被继承;修饰方法,表示该方法不能被重写;修饰变量,表示该变量的值不能被更改。
finally是在异常处理时用来进行资源释放的地方,finally中的代码在异常处理结束返回之前,一定会执行。
finalize是垃圾收集器在对某个对象进行清除前调用的方法,在这个方法中做一些必要的清理工作。该方法是在Object中定义的,所以所有类都拥有这个方法,当对它进行重写时,可以用来自定义地做些清理工作。