java常见面试题
-
**重载(overload) 和重写(override) 的区别?重载的方法能否根据返回类型进行区分? **
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中, 同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。 重载对返回类型没有特殊的要求。
-
方法重载的规则:
1.方法名一致,参数列表中参数的顺序,类型,个数不同。
2.重载与方法的返回值无关,存在于父类和子类,同类中。
3.可以抛出不同的异常,可以有不同修饰符。 -
方法重写的规则:
1.参数列表必须完全与被重写方法的一致,返回类型必须完全与被重写方法的返回类型一致。
2.构造方法不能被重写,声明为final的方法不能被重写,声明为static的方法不能被重写,但是能够被再次
声明。
3.访问权限不能比父类中被重写的方法的访问权限更低。
4.重写的方法能够抛出任何非强制异常(UncheckedException,也叫非运行时异常) ,无论被重写的方法是、否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
4.为什么函数不能根据返回类型来区分重载?
因为调用时不能指定类型信息,编译器不知道你要调用哪个函数。
例如:
float max(int a,int b);
int max(int a,int b);
当调用max(1,2)时,根本无法确定要调用哪个?但从这一点上来说不能根据返回类型来区分重载。
再对比下面两个方法,虽然它们有同样的方法名和参数名,但是根据返回值可以很明确的区分:
1.void f(){};
2.int f(){};
当编译器可根据上下文明确判断出其含义,比如 int x=f(),那么这样完全没有问题,但是我们也可能调用一个法,同时忽略返回值;我们通常把这称为”为它的副作用去调用一个方法”,因为我们关心的不是返回值,而是方法调用的其他效果。所以假如我们像下面这样调用方法: f(); Java怎样判断f()的具体调用方式呢?而且别人如何识别并理解代码呢?由于存在这一-类的问题, 所以不能。
函数的返回值只是作为函数运行之后的一个“状态" ,他是保持方法的调用者与被调用者进行通信的关键。并不能
作为某个方法的"标识”。
5.两个对象值相同(x.equals(y)==true),它们却有不同的hashCode值,这句话对吗?
不对,如果x.equals(y)==true,那么它们的hashCode值一定相同。
String x="abc";
String y="abc";
if(x.equals(y)==true) {
System.out.println("x的hashCode:"+x.hashCode());
System.out.println("y的hashCode:"+y.hashCode());
}
运行结果:
x的hashCode:96354
y的hashCode:96354
Java对于eqauls方法和hashCode方法是这样规定的: (1)如果两个对象相同(equals 方法返回true) ,那么它们的hashCode值一-定要相同; (2)如果两个对象的hashCode相同,它们并不一定相同。 当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。
关于equals和hashCode 方法,很多Java程序员都知道,但很多人也就是仅仅知道而已,在Joshua Bloch
的大作《Effective Java》(很多软件公司, 《Effective Java》、《Java 编程思想》以及《重构:改善既有代码质量》是Java程序员必看书籍,如果你还没看过,那就赶紧去买一本吧) 中是这样介绍equals 方法的。
首先equals方法必须满足自反性(x.equals(x)必须返回true) 、对称性(x.equals(y)返回true 时, y.equals(x)
也必须返回true) 、传递性(x.equals(y)和y.equals(z)都返回true 时, x.equals(z)也必须返回 true) 和一致性(当
x和y引用的对象信息没有被修改时,多次调用x.equals(y)应该得到同样的返回值),而且对于任何非null值的引
用x, x.equals(null)必须返回false.实现高质量的equals方法的诀窍包括: 1. 使用= =操作符检查"参数是否为这个
对象的引用"; 2.使用instanceof 操作符检查"参数是否为正确的类型"; 3.对于类中的关键属性,检查参数传入对象
的属性是否与之相匹配; 4.编写完equals方法后,问自己它是否满足对称性、传递性、-致性; 5.重写equals 时
总是要重写hashCode; 6. 不要将equals 方法参数中的Object 对象替换为其他的类型,在重写时不要忘掉
@Override注解
6.==和equals的区别?
==和equals的最大区别是一个是运算符一个是方法。
==:如果比较的对象是基本数据类型,则比较的是数值是否相等;如果比较的是引|用数据类型,则比较的是对象
的地址值是否相等。
equals():用来比较方法两个对象的内容是否相等。
注意: equals 方法不能用于基本数据类型的变量,如果没有对equals方法进行重写,则比较的是引用类型的变
量所指向的对象的地址。