1、关于下面的程序,哪个选项的说法是正确的?
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
byte a = 3,b=2; //1
byte c = a+b; //2
System.out.println(c);
}
}
A、编译通过,运行时打印出5
B、编译通过,运行时打印出23
C、编译不通过,在//2出有错误,因为此处f必须是一个byte类型的变量
D、编译不通过,在//1出有错误,不能这样定义变量
解析:java中涉及byte、short和char类型的运算操作首先会把这些值转换为int类型,然后对int类型值进行运算,最后得到int类型的结果。因此,如果把两个byte类型的值相加,最后会得到一个int类型的结果。如果需要得到byte类型结果,必须将这个int类型的结果显式转换为byte类型
把2处代码改为下面就正确了:byte c = (byte) (a+b); //2
2、以下程序错误的是:
A、short s=1;s=s+1; B、short s=1;s+=1;
解析:s+1为int,不能直接赋值给short,而B中是读取右s的地址+1
3、下面程序执行会出现错误吗?如果有错是什么错误?
public class PerttyTest {
public static void main(String[] args){
String i="123",s;
s=getStr(i);
System.out.println(s);
}
public String getStr(String s){
StringBuffer sb=new StringBuffer();
for(int i=s.length()-1;i>=0;i--){
sb.append(s.charAt(i));
}
return sb.toString();
}
}
解析:main函数是个static函数,getStr不是静态函数,不能在main中调用,或者将getStr声明为static的函数,或者实例化一个PerttyTest类来调用
4、谈谈final、finally、finalize的区别。
(1)final修饰符(关键字)
如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既声明为abstract,又被声明为final。
将变量或方法声明为final,可以保证它们在使用中不被改变。其初始化可以在两个地方:一是其定义处,也就是说在final变量定义时直接给其赋值;二是在构造函数中。这两个地方只能选其一。声明为final的方法同样只能使用,不能重写(overide)
(2)finally
在异常处理时提供finally块来执行任何清除操作。如果抛出一个异常,那么相匹配的catch子句就会执行,然后控制就会进入finally块。
(3)finalize
finalize是方法名。java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。
5、当你去编译和运行下面的代码时,会发生下面哪种情况?
class ExBase{
abstract public void martley(){
}
}
public class MyEx extends ExBase{
public static void main(String argv[]){
DataInputStream fi =new DataInputStream(System.in);
try{
fi.readChar();
}catch(IOException e){
System.exit(0)
}
finallly{Sytemt.out.println("Doing finally");}
}
}
A. 编译时错误
B. 程序运行的时候,等待一个键盘输入然后就跳出
C. 程序运行的时候,等待一个键盘输入,在屏幕上显示出“Doing finally”,然后跳出
D. 运行中立即跳出
解析:这是一道典型的误导人思维的题目。其实程序会产生的错误就想本地方法和抽象方法没有方法体一样。另外,abstract方法所在的类必须用abstract修饰。还需要注意一个问题,abstract类中却不一定有abstract方法。抽象类不能够生成对象,抽象类天生是被继承的。抽象类的抽象方法都只能用public、abstract修饰,接口的方法也是这样。
6、说明浅复制和深复制的区别?
⑴浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
⑵深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
举例说明:
class ShallowCopy implements Cloneable{
private Date begin;
public Date getBegin() {
return begin;
}
public void setBegin(Date begin) {
this.begin = begin;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
class DeepCopy implements Cloneable{
private Date begin;
public Date getBegin() {
return begin;
}
public void setBegin(Date begin) {
this.begin = begin;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
DeepCopy obj=null;
obj=(DeepCopy) super.clone();
obj.setBegin((Date) getBegin().clone());
return obj;
}
7、实现一个拷贝构造函数:
public class Test1 {
public int i;
public Test test;
public Test1() {
// TODO Auto-generated constructor stub
}
public Test1(Test1 t){
i=t.i;
test = new Test();
test.i=t.test.i;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//A a = new B();
Test1 t = new Test1();
t.i=9;
t.test=new Test();
t.test.i=10;
Test1 t1=new Test1(t);
System.out.println(t1.i);
System.out.println(t1.test.i);
}
}
class Test{
public int i;
public Test(){
}
public Test(Test t){
i=t.i;
}
}
8、Java中public,protected,private,default的区别?
public,protected,private是Java里用来定义成员的访问权限的,另外还有一种是“default”,也就是在成员前不加任何权限修饰符。
这四个修饰符的访问权限如下表:
-----------------------------------------------
类内部 package内 子类 package外
public 允许 允许 允许 允许
protected 允许 允许 允许 不允许
default 允许 允许 不允许 不允许
private 允许 不允许 不允许 不允许
-----------------------------------------------
Java的访问控制是停留在编译层的,也就是它不会再class文件中留下任何的痕迹,只在编译的时候进行访问控制的检查。
其实,通过反射的手段,是可以访问任何包下任何类中的成员的,例如,访问类的私有成员也是可能的。
9、Java中接口的方法只能是public abstract类型的,可以省略,变量只能是final static类型的,可以省略。
10、Java中equal和==的区别是什么?
首先看一段代码:
public class Test1{
public static void main(String args[]){
String a="1234";
String b="1234";
String c = new String("1234");
System.out.println(a==b);
System.out.println(a==c);
System.out.println(a.equals(c));
}
}
结果:
true
false
true
首先应该先了解java中String new和直接赋值的区别。
第二个为false的原因在于a和c指向的是不同的对象。==运用在基本数据类型的时候,通过比较他们的实际的值来判定是否相等,而用于比较引用类型的时候,则是比较两个引用的地址是否相等,也就是是否指向同一个对象。通过new来创建的字符串单独生成一个对象,所以a和c指向的不是同一个对象。
equal()方法是java.lang.object的方法,也就是所有的Java类都会有的方法。它可以被程序员覆盖重写,通过自定义的方式来判定两个对象是否相等。对于字符串String类来说,他的equal方法用来比较字符串的字符序列是否 完全相等。
11、Java中char的取值范围?
Java中char采用Unicode编码格式,用两个字节来表示一个字符,一共16bit,它所能表示的最大值为2的16次方
12、Java中char能否存储汉字?
char是可以存储汉字的,每个中文字符都有对应的Unicode编码。
13、Java中Overload(重载)和Override(覆盖)的区别
重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型,不关心返回值类型。
覆盖,是指在子类中对父类的某方法进行重新定义,其子类的该方法名以及参数位置和个数以及返回值均与父类相同,从而在调用子类的该方法时,不会执行父类的方法。如果在父类中以final定义的方法,在子类中无法重写。
14、以下代码的输出是什么?
public class Test1 {
public Test1() {
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
A a = new B();
System.out.println("----------------");
B b = new B();
}
}
class A{
static{
System.out.println("AAAAAAAAAAAAAA static");
}
public A() {
//super();
System.out.println("AAAAAAAAAAAAAA");
// TODO Auto-generated constructor stub
}
}
class B extends A{
static{
System.out.println("BBBBBBBBBBBBBBB static");
}
public B() {
//super();
System.out.println("BBBBBBBBBBBBBB");
}
}
结果:
AAAAAAAAAAAAAA static
BBBBBBBBBBBBBBB static
AAAAAAAAAAAAAA
BBBBBBBBBBBBBB
----------------
AAAAAAAAAAAAAA
BBBBBBBBBBBBBB
static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法
15、Java中的几种引用方式:强引用、软引用、弱引用、虚引用的区别?
在JDK1.2以前的版本中,当一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于可触及状态,程序才能使用它。这 就像在日常生活中,从商店购买了某样物品后,如果有用,就一直保留它,否则就把它扔到垃圾箱,由清洁工人收走。一般说来,如果物品已经被扔到垃圾箱,想再 把它捡回来使用就不可能了。
但有时候情况并不这么简单,你可能会遇到类似鸡肋一样的物品,食之无味,弃之可惜。这种物品现在已经无用了,保留它会占空间,但是立刻扔掉它也不划算,因 为也许将来还会派用场。对于这样的可有可无的物品,一种折衷的处理办法是:如果家里空间足够,就先把它保留在家里,如果家里空间不够,即使把家里所有的垃 圾清除,还是无法容纳那些必不可少的生活用品,那么再扔掉这些可有可无的物品。
从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。
1) 强引用
平时我们编程的时候例如:Object object=new Object();那object就是一个强引用了。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空 间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。
2) 软引用(SoftReference)
如果一个对象只具有软引用,那就类似于可有可物的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只 要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。 软引用可以和一个引用队列(ReferenceQueue)联 合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
3) 弱引用(WeakReference)
如果一个对象只具有弱引用,那就类似于可有可物的生活用品。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它 所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。 弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回 收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
4) 虚引用(PhantomReference)
"虚引用"顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在 任何时候都可能被垃圾回收。 虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队
列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
16、String str1="abc" 和String str2=new String("abc")的区别?
Java虚拟机在执行这段代码时,遇到双引号操作符,它会自动创建一个String对象,该String对象所代表的值就是abc,然后再返回该对象的一个引用。
对应str1字符串来说,它的创建过程同上所述。在Java5.0及其以后的版本,在创建该对象之前,JVM会在String对象池中去搜索该字符串对象是否已经被创建,如果已经被创建,则直接返回一个引用,否则先创建再返回引用。
而str2字符串变量,它的创建过程就要多一个步骤。它会额外的创建一个新的String对象,也就是new关键字的作用,并且返回一个引用给str2 。
Java中有对象池的概念,Java虚拟机启动时候会实例化9个对象池,分别用来存储8中基本类型的包装类和String对象。对象池的存在是为了频繁的创建和销毁对象而影响系统性能。
str1是在对象池中取对象,str2方法直接生成新的对象。
任何情况下,只要new一个String对象都是创建了新的对象。
因此表达式str1==str2的结果是false的。
17、String不能被继承,String作为方法参数时是传值而不是传引用
Java基础面试题,布布扣,bubuko.com
Java基础面试题
原文:http://blog.csdn.net/heqiangflytosky/article/details/20954713