默认情况面向对象有3大特性(封装、继承、多态),问4大特性就把抽象加上去。
clone
?clone()
实现最简单也最高效。&
和&&
的区别false
,右边的表达式会被直接短路掉,不会进行运算。但是&遇到左边的变道时的值是false
,还会继续运算右边的表达式。(逻辑或(|)与短路或(||)的区别也是如此)break A;
可以跳出多重循环。(x.equals(y) == true)
,但却可能有不同的hashCode
,这句话对不对?(x.equals(y) == true)
,它们的hashCode
一定相同。如果两个对象的
hashCode
相同,它们的equals
不一定相同
String
String
类是final
修饰的类,不可被继承。(overload)
和重写(override)
的区别?重载的方法能否根据返回类型进行区分?Unicode
,一个char
类型占2个字节(16比特),一个中文占2个字节,所以放一个中文没问题。A a = new B();
那么a调用的是A中的方法,因为a在内存中指向的对象是A。可以理解为 B b = new B(); A a = b;
向上转型。CheckedException
和运行时异常(非强制性异常)也叫RunntimeException
。只有Java语言提供了编译时异常,Java认为编译时异常都是可以被处理的异常,所以Java程序必须显式处理编译时异常。如果程序没有处理Checked异常,改程序在编译时就会发生错误无法继续编译。这体现了Java的设计哲学:没有完善错误处理的代码根本没有机会被执行。对Checked异常处理方法有两种:
try...catch
块来处理该异常。public int getNum(){
try{
int a = 1/0;
return 1;
} catch(Exception e) {
return 2;
} finally {
return 3;
}
}
int a = 1/0;
语句存在异常,会被catch(Exception e)
捕捉,返回2,最后还会执行finally
中的语句,最终返回3。Throwable
类;Error
类一般指与虚拟机有关的问题,如系统崩溃、虚拟机错误、内存空间不足等,这类错误会导致的程序中断,仅靠程序本身是无法恢复和预防的,建议让程序终止Exception
类表示程序可以处理的异常,可以捕获且可能恢复。这类异常,应该尽可能处理。CheckedException
);而系统异常(RunntimeException
)可以处理也可以不处理。java.lang.NullPointerException
空指针异常
java.lang.ClassNotFoundException
找不到类异常
java.lang.IllegalArgumentException
方法传递参数错误java.lang.ClassCastException
数据类型转换异常SQLException
SQL异常throw
:
throws
:
final
:用于声明属性、方法和类,分别表示属性不可变,方法不可覆盖,类不可继承;finally
:异常处理语句结构的一部分, 表示总是执行;finalize
:Object类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法。可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。Java5
以前switch(expr)
中,expr
只能是byte
、short
、char
、int
。Java5
开始,Java引入了枚举类型,expr也可以是enum
类型。Java7
开始,expr还可以是String
类型。数组
没有length()方法,而是有length属性。String
有length()方法。String
是只读字符串,引用的字符串内容不能被改变,底层是char[]
,Java8
是byte[]
;StringBuilder/StringBuffer
表示字符串对象可以通过各种方法来达到简单的增删改,底层是char[]
,默认16字符空间
,会自动维护数组的扩容;StringBuilder
是Java5
中引入的,它和StringBuffer
的方法完全相同,区别在于它是在单线程环境下使用的;StringBuffer
是线程安全的,方法都被synchronized
修饰。所以StringBuilder的效率理论上比StringBuffer高。String对象的
intern()
方法会得到字符串对象在常量池中对应的版本的引用。
short s1 = 1;
s1 = s1 + 1;
判断:错误。由于1是int类型,因此s1+1运算结果也是int型,需要强制类型转换才能赋给short型。
------------------------------
short s1 = 1;
s1 += 1;
判断:正确。s1 += 1 是编译器优化的结果,含有隐式的强制类型转换,可以理解为s1 = (short)(s1+1)
public static void main(String[] args) {
Integer a = new Integer(3);
Integer b = 3; // 将3自动装箱成Integer
int c = 3;
System.out.println(a==b); // false 引用的不是同一个对象
System.out.println(a.equals(b)); // true 内容相等
System.out.println(a==c); // true a自动拆箱成int类型再和c比较
}
public static void main(String[] args) {
Integer f1 = 100,f2 = 100,f3=150,f4=150;
System.out.println(f1==f2); // true
System.out.println(f3==f4); // fa;se
}
如果整形字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象。
parseXXX(String)
或 valueOf(String)
(+)
valueOf()
方法返回相应字符串inputStream
)和输出流(outputStream
)InputStream
和OutputStream
)和字符流(继承于InputStreamReader
和OutputStreamWriter
)Serializable
接口,该接口没有需要实现的方法,只是为了标注该对象可被序列化,然后使用一个输出流(如:FileOutputStream
)来构造一个对象流(ObjectOutputStream
)对象,接着使用对象流对象的writeObject(Object obj)
方法就可以将参数为obj的对象写出,要恢复的话则用输入流(ObjectInputStream
)。public class HashMapTest {
public static void main(String[] args) {
HashMap<Integer, User> users = new HashMap<>();
users.put(1, new User("张三", 22));
users.put(2, new User("李四", 12));
users.put(3, new User("王五", 66));
System.out.println("排序前:" + users);
HashMap<Integer, User> sortHashMap = sortHashMap(users);
System.out.println("排序后:"+sortHashMap);
ArrayList<Object> objects = new ArrayList<>();
// 排序前:{1=User{name='张三', age=22}, 2=User{name='李四', age=12}, 3=User{name='王五', age=66}}
// 排序后:{3=User{name='王五', age=66}, 1=User{name='张三', age=22}, 2=User{name='李四', age=12}}
}
public static HashMap<Integer, User> sortHashMap(HashMap<Integer, User> map) {
// 首先拿到map的键值对集合
Set<Map.Entry<Integer, User>> entrySet = map.entrySet();
// 将Set转为List,为了使用工具类的排序方法
List<Map.Entry<Integer, User>> list = new ArrayList<>(entrySet);
// 使用Collections集合工具类对list进行排序,排序规则使用匿名内部类实现
Collections.sort(list, new Comparator<Map.Entry<Integer, User>>() {
@Override
public int compare(Map.Entry<Integer, User> o1, Map.Entry<Integer, User> o2) {
// 根据User的age倒序进行排序(默认从小到大,倒序是从大到小)
return -(o1.getValue().getAge() - o2.getValue().getAge());
}
});
// 创建一个新的有序的HashMap子类的集合
LinkedHashMap<Integer, User> linkedHashMap = new LinkedHashMap<>();
// 将list中的数据存储在linkedHashMap中
for (Map.Entry<Integer, User> entry : list) {
linkedHashMap.put(entry.getKey(), entry.getValue());
}
return linkedHashMap;
}
}
ArrayList
、HashSet
、HashMap
是线程安全的吗?如何把它们变成线程安全的?Vector
和HashTable
是线程安全的,它们的核心方法声明上都加上了synchronized
。Java基础编程-Java集合
Java基础编程-多线程
可以展开说线程池如何用、好处、启动策略
Class.forName(className)
类名.class
this.getClass()
InvocationHandler
接口的invoke()
方法,代理的是接口,所以业务类必须要实现这个接口,通过Proxy
里的newProxyInstance()
得到代理对象。CGLIB
,代理的是类,不需要业务类实现接口,通过派生的子类来实现代理。AOP
编程就是基于动态代理实现的。参考文章:Java动静态代理
参考文章:设计模式
参考文章:深入理解JVM-内存模型(jmm)和GC
Class.forName("com.hjl.hello")
)复习文章:Java基础编程-Lambda