抽象、封装、继承、多态。
多态性是指允许不同子类型的对象对同一消息做出不同的响应。
多态的实现是靠重载和重写。
重载是编译时多态,重写是运行时多态。
重写规则:
重载规则:
在调用时,无法指定类型信息,编译器不能直到程序调用的是哪个方法。
在JVM中,要重载一个方法,除了要与原方法有相同的简单名称外,还必须有一个与原方法不同的特征签名。特征签名就是方法中的参数在常量池中的引用的集合,不包括返回值类型。Class文件的特征签名的范围更大,包括返回类型,应为JVM规范和Java语言规范不同。
byte
, 1short
, 2int
, 4long
, 8float
, 4double
, 8char
, 2boolean
, 4boolean
可以用1bit
存储,JVM在编译期将boolean转换为int
存储。基本类型都有对应的包装类型,基本类型与包装类型之间的赋值使用自动装箱和拆箱完成。
String
被声明为final
,不可修改。
Java8中String
使用char
数组存储,Java9中是用byte
数组存储,同时用coder
标识编码方式。
String
是线程安全的;可以作为map的key
,缓存hash值;String
创建过的对象会放在String Pool中。
支持char
, byte
, short
, int
, Character
, Byte
, Short
, Integer
, String
, enum
。
String
不可变,StringBuilder
和StringBuffer
可变;
StringBuilder
线程不安全,String
和StringBuffer
线程安全。
含有抽象方法的类一定是抽象类,抽象类不能被实例化。
接口在Java8之前不能有任何方法,是完全抽象的类。在Java8之后,可以定义default
方法。
区别:
public
的,字段是public
,static
,final
的;抽象类没有这种限制;super
和this
关键字。static
修饰,静态内部类可以通过外部类的类名直接访问内部类。调用顺序:
在运行状态中,对于任意一个类,都知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性;这种动态获取类的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
优点:
缺点:
Class.forName("全限定类名")
;类名.class
;对象.getClass()
;clz.getConstructor([String.class]).newInstance([参数])
;clz.newInstance()
;相当于new 类名()
;Filed c = clz.getFields
;获得所有public
字段,包括父类中的字段;Filed c = clz.getDeclaredFields()
;获得某个类的所有申明字段,不包括父类字段;clz.getMethod("方法名", class ... paramType)
,只能获取公共的;clz.getDeclareMethod("方法名")
,获取任意修饰的方法,不能执行私有;M.setAccessiable(true)
,让私有方法可以执行;异常是发生在程序执行过程中阻碍程序正常执行的错误操作,只要在Java语句执行中产生异常则一个异常对象就会被创建。Throwable
是所有异常的父类,它有两个直接子类Error
和Exception
,其中Exception
又被继续分为Checked Exception
(受检异常)和Runtime Exception
(运行时异常)。Error
是JVM不能处理的错误;受检异常在程序中能预期且要尝试修复(使用try-catch
捕获异常,并进行处理;或用thows
关键字抛出);运行时异常又称为不受检异常,是程序运行时出现的异常,可能会导致程序崩溃,不要求被处理或用throws
抛出。
throw
和throws
的区别是什么?throw
使用的位置在方法中,后面跟的是异常对象实例,表示抛出异常,由方法体内语句处理,如果方法中有throw
抛出RuntimeException
及其子类则申明上可以没有throws
。
throws
的使用位置在方法参数括号后面,后面跟的是一个或者多个异常类名且用逗号隔开,表示抛出异常并交给调用者去处理,如果后面跟的是RuntimeException
及其子类则方法可以不用处理,如果后面跟的是Exception
及其子类则必须要编写代码进行处理或者调用的时候抛出。
try-catch
代码块处理或用throws
关键字抛出,运行时异常在程序中不要求被处理或用throws
抛出;Exception
是所有受检异常的基类,而RuntimeException
是所有运行时异常的基类;FileNotFoundException
),而运行时异常通常是由于代码错误引起(如NullPointerException
);Error
和Exception
有什么区别?Error
表示系统级错误,是Java运行环境内部错误或者硬件问题不能指望程序来处理这样的问题,除了退出运行外别无选择,它是Java虚拟机抛出的。
Exception
表示程序需要捕捉、需要处理的异常,是由于程序设计的不完善而出现的问题,是程序可以处理的问题。
异常链是指在进行一个异常处理时,抛出了另外一个异常,由此产生了一个异常链条大多用于将受检异常封装成为非受检异常。特别注意如果你因为一个异常而决定抛出另一个新的异常时,一定要包含原有的异常这样处理程序才可以通过getCause()
和initCause()
方法来访问异常最终的根源。
可以通过继承Exception
类或其任何子类来实现自定义异常类,自定义异常类可以有自己的变量和方法来传递错误代码或其他异常相关信息来处理异常。
null
,这样可以避免很多NullPointerException
异常;catch
到了异常,至少打印一下,以便排查问题;finally
中使用return
语句或者抛出异常,如果调用的其它代码可能抛出异常则应该捕获异常并进行处理,因为finally
中return
不仅会覆盖try
和catch
内的返回值,而且还会掩盖try
和catch
内的异常;throws
后面尽量定义具体的异常列表,不要直接throws Exception
;catch
中压制异常(即什么也不处理直接return
);finally
块中抛出异常,不然第一个异常的调用栈会丢失。if
语句进行条件判断的情况下却使用异常处理是非常不好的习惯,会严重影响性能。Throwable
类,因为 Error
是 Throwable
类的子类,当应用抛出 Errors
的时候一般都是不可恢复的情况。在集合中存储对象并在使用前进行类型转换很不方便,泛型就是为了防止这种情况的发生。
它提供了编译器的类型安全,确保你只能把正确类型的对象放入集合中,避免了在运行时出现ClassCastException
。
泛型是通过类型擦除来实现的,编译器在编译时擦除了所有类型相关的信息,所以在运行时不存在任何类型相关信息。你无法在运行时访问到类型参数,因为编译器已经把泛型类型转换成了原始类型。
限定通配符对类型进行了限制。有两种限定通配符,一种是 extends T>
,它确保类型必须是T的子类来设定类型的上界;另一种是 super T>
,它确保类型必须是T的父类来设定类型的下界。泛型类型必须用限定内的类型来进行初始化,否则会导致编译错误。
另一方面,>
表示了非限定通配符,因为>
可以用任意类型来代替。
用类型占位符来代替原始类型。
public V put(K key, V value){
return cache.put(key, value);
}
LinkedHashMap
的removeEldestEntry()
的方法即可public class UseLinkedHashMapCache<K, V> extends LinkedHashMap<K, V> {
private int cacheSize;
public UseLinkedHashMapCache(int cacheSize) {
super(16, 0.75f, true);
// true表示让LinkedHashMap按照访问顺序来进行排序,最近访问的放在头部,最老访问的放在尾部。
this.cacheSize = cacheSize;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest){
// 当map中的数据量大于指定的缓存个数的时候,就自动删除最老的数据。
return size() > cacheSize;
}
}
List
传递给一个接受List
参数的方法吗?这样会导致编译错误。因为List
可以存储任何类型的对象包括String
, Integer
等,而List
却只能来存储String
。可以加上 extends Object>
,来解决。
Array
中可以用泛型吗?不行,用List
代替Array
,因为List
可以提供编译时期的类型安全保证,而Array
不行。