面试题1
1 == 和 equals 的区别是什么?
1)==既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址
2)equals的话,它是属于java.lang.Object类里面的方法,如果该方法没有被重写过默认也是 ==;我们可以看到String等类的equals方法是被重写过的,而且String类在日常开发中equals 用的比较多,久而久之,形成了equals是比较值的错误观点。
3)具体要看自定义类里有没有重写Object的equals方法来判断。
4)通常情况下,重写equals方法,会比较类中的相应属性是否都相等。
equals 和== 最大的区别是一个是方法一个是运算符。
==:如果比较的对象是基本数据类型,则比较的是数值是否相等;如果比较的是引用数据类型,则比较的是对象的地址值是否相等。
equals():用来比较方法两个对象的内容是否相等。
注意:equals 方法不能用于基本数据类型的变量,如果没有对 equals 方法进行重写,则比较的是引用类型的变
量所指向的对象的地址。
2 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
结论:
两个对象equals相等,则它们的hashcode必须相等,反之则不一定。
两个对象==相等,则其hashcode一定相等,反之不一定成立。
不一定,可以举HashMap的例子,虽然经过hash算法得到的值(底层数组的索引)相同,但依然还会引入链表地址法把相同Node头插到链表里,如果元素的内容不相同,equal是()也不为true。
hashCode 的常规协定:
1.在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
2.两个对象的equals()相等,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
3.两个对象的equals()不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不要求一定生成不同的整数结果。但是,为不相等的对象生成不同整数结果可以提高哈希表的性能。
3 .final 在 java 中有什么作用?
final作为Java中的关键字可以用于三个地方。用于修饰类、类属性和类方法。
特征:凡是引用final关键字的地方皆不可修改!
(1)修饰类:表示该类不能被继承;
(2)修饰方法:表示方法不能被重写;
(3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。
4 java 中的Math.round(-1.5) 等于多少?
Math.round(-1.5)的返回值是-1
5 String 属于基础的数据类型吗?
String 是引用类型,底层用 char 数组实现的。
6 java 中操作字符串都有哪些类?它们之间有什么区别?
1、String类与StringBuilder类的比较
1.1) String类与StringBuilder类相同点:
1.1.1) String与StringBuffer两个类都完成对字符串的各种操作;
1.1.2) String类与StringBuffer类都被放到了java.lang包中
1.2) String类与StringBuilder类两者的主要区别在于:
1.2.1) String类对象中的内容初始化不可以改变
1.2.2)StringBuffer类对象中的内容可以改变
2、StringBuffer与StringBuilder的比较
2.1) StringBuffer与StringBuilder的相同点
2.1.1) StringBuffer和StringBuilder都是长度可变的字符串。 2.1.2) 两者的操作基本相同。
2.2) 两者的主要区别在于
2.2.1)StringBuffer类是线程安全的;
2.2.2)StringBuilder类是线程不安全的。
2.2.3)StringBuffer在JDK1.0中就有,而StringBuilder是在JDK5.0后才出现的。
2.2.4)StringBuilder的一些方法实现要比StringBuffer快些。
7 String str="i"与 String str=new String(“i”)一样吗?
不一样,体现在内存的分配方式不一样。第一种情况JVM会把str分配到常量池中,第二种情况JVM会把str分配到堆内存中。
8 普通类和抽象类有哪些区别?
抽象类不能被实例化
抽象类可以有抽象方法,抽象方法只需申明,无需实现
含有抽象方法的类必须申明为抽象类
抽象的子类必须实现抽象类中所有抽象方法,否则这个子类也是抽象类
抽象方法不能被声明为静态
抽象方法不能用private修饰
抽象方法不能用final修饰
9 抽象类能使用 final 修饰吗?
不能 抽象类的就是要子类继承然后实现内部方法的。但是final修饰的类是不能再被继承和修改的。所以不能用final修饰。
普通类、抽象类和接口区别:
- 普通类可以实例化,接口都不能被实例化(它没有构造方法),抽象类如果要实例化,抽象类必须指向实现所有抽象方法的子类对象(抽象类可以直接实例化,直接重写自己的抽象方法),接口必须指向实现所有所有接口方法的类对象。
- 抽象类要被子类继承,接口要被子类实现
- 接口只能做方法的声明,抽象类可以做方法的声明,也可以做方法的实现。
- 接口里定义的变量只能是公共的静态常量,抽象类中定义的变量是普通变量
- 抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类的抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如果不能全部实现接口方法,那么该类只能是抽象类
- . 抽象方法只能声明,不能实现。接口是设计的结果,抽象类是重构的结果。
- 抽象类里可以没有抽象方法。
- 如果一个类里有抽象方法,那么该类只能是抽象类。
- 抽象方法要被实现,所以不能是静态的,也不能是私有的
- 接口可以继承接口,并可多继承接口,但类只能单继承。(重要啊)
- 接口中的常量:有固定的修饰符-public static final(不能用private和protected修饰/本质上都是static的而且是final类型的,不管加不加static修饰)。
- 接口中的抽象方法:有固定的修饰符-public abstract
- 接口细节:
若接口中方法或变量没有写public,static,final / public,abstract ,会自动补齐 。
接口中的成员都是共有的。
接口与接口之间是继承关系,而且可以多继承。
接口不能被实例化 一个类可以实现多个接口
在java开发中,我们经常把常用的变量,定义在接口中,作为全局变量使用,访问形式:接口名.变量名。 一个接口不能继承其它的类,但是可以继承别的接口 一个重要的原则:当一个类实现了一个接口,要求该类把这个接口的所有方法全部实现
注意:① 抽象类和接口都是用来抽象具体的对象的,但是接口的抽象级别更高。② 抽象类可以有具体的方法和属性,接口只能有抽象方法和静态常量。③ 抽象类主要用来抽象级别,接口主要用来抽象功能。④ 抽象类中,且不包含任何的实现,派生类必须覆盖它们。接口中所有方法都必须是未实现的。⑤ 接口方法,访问权限必须是公共的 public。⑥ 接口内只能有公共方法,不能存在成员变量。⑦ 接口内只能包含未被实现的方法,也叫抽象方法,但是不能用 abstract 关键字。⑧ 抽象类的访问速度比接口要快,接口是稍微有点慢,因为它需要时间去寻找在类中实现的方法。⑨ 抽象类,除了不能被实例化外,与普通 java 类没有任何区别。⑩ 抽象类可以有 main 方法,接口没有 main 方法。⑪ 抽象类可以用构造器,接口没有。⑫ 抽象方法可以有 public、protected 和 default 这些修饰符,接口只能使用默认 public。⑬ 抽象类,添加新方法可以提供默认的实现,不需要改变原有代码。接口添加新方法,子类必须实现。⑭ 抽象类的子类用 extends 关键字继承,接口用 implements 来实现。
二、什么时候用抽象类和接1. 若果你拥有一些方法并且想让他们中的一些有默认实现,那就用抽象类。2. 如果你想实现多重继承,那么必须使用接口。由于 java 不支持多继承,子类不能继承多个父类,但是可以实现多个接口,因此你可以使用接口来实现它。3. 如果基本基本功能在不断变化,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么所有实现类都需要改变。