Java面试题
java基础
1.java面向对象的理解?面向对象的特征?
整体上是封装、继承、多态、抽象。
首先面向对象是一种思想。在java中万事万物皆对象。类是对相同事物的一种抽象、是不可见的,对象具体的、可见的。由对象到类的过程是抽象的过程,由类到对象的过程是实例化的过程。面向对象的三大特征分别是封装、继承和多态。
封装隐藏了类的内部实现机制,对外界而言它的内部细节是隐藏的,暴露给外界的只是它的访问方法。例如在属性的修饰符上我们往往用的private私有的,这样其它类要想访问就通过get和set方法。因此封装可以程序员按照既定的方式调用方法,不必关心方法的内部实现,便于使用; 便于修改,增强代码的可维护性。
继承在本质上是特殊~一般的关系,即常说的is-a关系。子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的一些属性或方法。比如从猫类、狗类中可以抽象出一个动物类,具有和猫、狗、虎类的共同特性(吃、跑、叫等)。通过extends关键字来实现继承。Java中的继承是单继承,即一个子类只允许有一个父类。
Java多态是指的是首先两个类有继承关系,其次子类重写了父类的方法,最后父类引用指向子类对象。如Animal a=new Dog();这行代码就体现了多态。
2.Java中实现多态的机制是什么?
Java中的多态靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存 里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。
3.构造方法有哪些特性?
名字与类名相同;没有返回值,但不能用void声明构造函数;生成类的对象时自动执行,无需调用。
4.构造器(constructor)是否可被重写(override)?
构造器不能被继承,因此不能被重写,但可以被重载。
5.this与super的区别?
super:它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名 (实参)
this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
super()和this()区别是:
- super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
- super()和this()均需放在构造方法内第一行。尽管可以用this调用一个构造器,但却不能调用两个。
- this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语 句,就失去了语句的意义,编译器也不会通过。
- this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
6.Java中重写和重载有哪些区别?
方法的重载和重写本质都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态。
方法重载的规则:
- 方法名一致,
- 参数列表不同(参数顺序不同或者参数类型不同或者参数个数不同)。
- 重载与方法的返回值无关,这个很关键。
方法重写的规则:
- 参数列表和返回值类型必须完全与父类的方法一致
- 构造方法不能被重写,声明为 final 的方法不能被重写,声明为 static 的方法不能被重写,但是能够被再次声明。
- 访问权限不能比父类中被重写的方法的访问权限更低。
- 重写的方法能够抛出任何检查异常(编译时异常),但是重写的方法不能抛出比被重写方法声明的更广泛的运行时异常。
7.接口和抽象类有哪些区别?
- 接口中的所有方法都是抽象的,而抽象类可以有抽象方法,也可以有实例方法。
- 类需要继承,接口需要实现。一个类可以实现多个接口,但只能继承一个父类但接口却可以继承多接口。
- 接口与实现它的类不构成继承体系,即接口不是类体系的一部分。因此,不相关的类也可以实现相同的接口,而抽象类是属于类的继承体系,并且一般位于类体系的顶层。
8.接口是否可继承(extends)接口? 抽象类是否可实现(implements) 接口? 抽象类是否可继承具体类(concrete class)?
接口可以继承接口。抽象类可以实现(implements)接口,抽象类可继承具体类,但前提是具体类必须有明确的构造函数。
9.描述一下值传递和引用传递的区别?
- 值传递是指在调用函数时将实际参数复制一份到函数中,这样的话如果函数对其传递过来的形式参数进行修改,将不会影响到实际参数。
- 引用传递是指在调用函数时将对象的地址直接传递到函数中,如果在对形式参数进行修改,将影响到实际参数的值。
10.Java中==和equals有哪些区别?
- equals 和 == 最大的区别是一个是方法一个是运算符。
- 基本类型中,== 比较的是数值是否相等。equals方法是不能用于基本数据类型数据比较的,因为基本数据类型压根就没有方法。
- 引用类型中,== 比较的是对象的地址值是否相等。equals方法比较的是引用类型的变量所指向的对象的地址是否相等。因为String这个类重写了equals方法,比较的是字符串的内容。
11.hashcode方法和equals方法区别?
- 在Java中,每个对象都可以调用自己的hashCode方法得到自己的哈希值(hashCode),相当于对象的指纹信息,通常说世界上没有完全一样的指纹,但是在Java中没有这么绝对,我们依然可以用hashCode值来做一些提前的判断。
- 如果两个对象的hashCode值不一样,那么他们肯定是不同的两个对象;
- 如果两个对象的hashCode值一样,也不代表就是同一个对象;
- 如果两个对象的equals方法相等,那么他们的hashCode值一定相等。
- 在Java的一些集合类的实现中,在比较两个对象的值是否相等的时候,会根据上面的基本原则,先调用对象的hashCode值来进行比较,如果hashCode值不一样,就可以认定这是两个不一样的数据,如果hashCode值相同,我们会进一步调用equals()方法进行内容的比较。
12.为什么重写 equals 方法必须重写 hashcode 方法?
- equals 方法是用来比较对象大小是否相等的方法,hashcode 方法是用来判断每个对象 hash 值的一种方法。如果只重写 equals 方法而不重写 hashcode 方法,很可能会造成两个不同的对象,它们的 hashcode 也相等,造成冲突。
- 例如:String str1 = “通话”; String str2 = “重地”;它们两个的 hashcode 相等,但是 equals 可不相等。
13.两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。
Java对于eqauls方法和hashCode方法是这样规定的:
- 如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;
- 如果两个对象的hashCode相同,它们并不一定相同。
当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。
14.抽象的(abstract)方法是否可同时是静态的(static), 是否可同时是本地方法(native),是否可同时被 synchronized?
都不能。
- 抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。
- 本地方法是由本地代码(如 C++ 代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。
- synchronized 和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
15.final和static的区别?
static属于类级别的不可变,而final是对象级别的不可变。
16.final与finally、finalize 的区别?
- final:用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,被其修饰的类不可继承。
- finally:异常处理语句结构的一部分,表示总是执行。
- finalize:Object 类的一个方法,当java对象没有更多的引用指向的时候,系统会自动的由垃圾回收器来负责调用此方法进行回收前的准备工作和垃圾回收。
17.静态变量和实例变量区别?
- 静态变量: 静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有一份,在类的 加载过程中,JVM只为静态变量分配一次内存空间。
- 实例变量: 每次创建对象,都会为每个对象分配成员变量内存空间,实例变量是属于实例对象 的,在内存中,创建几次对象,就有几份成员变量。
18.静态方法和实例方法有何不同?
静态方法和实例方法的区别主要体现在两个方面:
- 在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的 方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
- 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法), 而不允许访问实例成员变量和实例方法;实例方法则无此限制。
19.指出下面程序的运行结果?
class A{
static{
System.out.print("1");
}
public A(){
System.out.print("2");
}
}
class B extends A{
static{
System.out.print("a");
}
public B(){
System.out.print("b")