1. Java泛型和类型擦除
- 泛型即参数化类型,在创建集合时,指定集合元素的类型,此集合只能传入该类型的参数
- 类型擦除:Java编译器生成的字节码文件不包含反省信息,所以在编译时擦除:
- 泛型用最*父类替换
- 移除
2. 如何将字符串反转?
- 使用StringBuilder或者StringBuffer的reverse()方法,如
package otherDemo;
public class StrReverse {
public static void main(String[] args) {
// StringBuffer reverse
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("abcdefg");
System.out.println(stringBuffer.reverse());
// StringBuilder reverse
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("abcdefg");
System.out.println(stringBuilder.reverse());
}
}
运行结果
3. String类的常用方法有哪些?
- indexOf() : 返回指定字符的索引
- charAt() : 返回指定索引处的字符
- replace() : 字符串替换
- trim() :去除字符串两端空白
- split():分割字符串,返回一个分割后的字符串数组
- getBytes(): 返回字符串的byte类型数组
- length() :返回字符串长度
- toLowerCase() :将字符串转成小写字母
- toUpperCase() : 将字符串转成大写字符
- substring() : 截取字符串
- equals() : 字符串比较
4. 抽象类必须要有抽象方法吗?
- 不需要,抽象类不一定非要有抽象方法,如
abstract class Dog{
public static void say(){
System.out.println("汪~");
}
}
5. 抽象类和普通类有什么区别?
- 普通类不能包含抽象方法, 抽象类可包含抽象方法
- 抽象类不能直接实例化,普通类可直接实例化
6. 接口和抽象类有什么区别?
- 实现:抽象类的子类使用extends来继承;接口必须使用implements来实现接口;一个类实现接口的话要实现接口的所有方法,而抽象类不一定
- 构造函数:抽象类可以有构造函数;接口不能有
- 实现数量:类可以实现多个接口,但只能继承一个抽象类
- 访问修饰符:接口中的方法默认使用public修饰;抽象类中的方法可以是任意访问修饰符
7. 以下代码中,s5==s2返回什么?
String s1 = "ab";
String s2 = "a"+"b";
String s3 = "a";
String s4 = "b";
String s5 = s3 + s4;
- 返回false。在编译过程中,编译器会直接将s2直接优化为"ab",将其放置在常量池中;而s5则是被创建在堆区,相当于s5=new String(“ab”);
8. String中的intern()
- String中的intern()是个Native方法,它会首先从常量池中查找是否存在该常量值的字符串,若不存在则现在常量池中创建,否则直接返回常量池中已经存在的字符串的引用,比如
String s1 = "aa";
String s2 = s1.intern();
System.out.println(s1==s2); // true
- 以上代码将返回true, 因为在"aa"会在编译阶段确定下来,并放置字符串常量池中,因此最终s1和s2引用的是同一个字符串常量对象
9. 什么是编译器常量?使用它有什么风险?
- 公共静态不可变。即public static final 修饰的变量就是我们所说的编译期常量。这里的public可选的。实际上这些变量在编译时会被替换掉,因为编译器明确的能判断出这些变量的值(相当于C++中的宏替换)
- 编译器常量虽然能够提升性能,但是也存在一些问题:你使用了一个内部的或第三方库中的公有编译时常量,但是这个值后面被其他人改变了,但是你的客户端没有重新编译,这意味着你仍然在使用被修改之前的常量值
10. Object常用方法总结
Object是一个特殊的类,是所有类的父类。它主要提供了以下11个方法:
1. public final native Class<?> getClass() // native方法,用于返回当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写
2. public native int hashCode() // native方法,用于返回对象的哈希码,主要使用在哈希表中,如JDK的HashMap
3. // 用于比较两个对象的内存地址是否相等,String类对该方法进行了重写用户比较字符串的值是否相等
public boolean equals(Object obj)
4. // native方法,用于创建并返回当前对象的一份拷贝。一般情况下,任何对象x, 表达式x.clone()!=x 为true,
// x.clone.getClass() == x.getClass()为true。Object本身没有实现Cloneable接口,所以不重写clone方法
// 并且进行调用的话会发生CloneNotSupportedException异常
public boolean Clone() throws CloneNotSupportedException
5. // 返回类的名字@实例的哈希码的16进制的字符串,建议Object所有的子类都重写这个方法
public String toString()
6. // native方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于锁的概念)。如果有多个线程在等待只会任意唤醒一个
public final native void notify()
7. // native方法,并且不能重写。和notify一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程
public final native void notifyAll()
8. // native方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁。timeout是等待时间
public final native void wait(long timeout) throws InterruptedException
9. // 多了nanos参数,这个参数表示额外时间(以毫微秒为单位,范围是0-999999).所以超时的时间还需要加上nanos毫秒
public final void wait(long timeout, int nanos) throws InterruptedException
10. // 跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念
public final void wait() throws InterruptedException
11. 实例被垃圾回收器回收的时候触发的操作
protected void finalize() throws Throwable{}
上一篇: Java面试手册V2.0+突击V3.0知识点整理(三)