1、动态绑定属性是没有的 方法有动态绑定
class one{
private int i = 10;
public int show(){
return getI()+20;
}
public int show2(){
return i+10;
}
public int getI() {
return i;
}
}
class two extends one{
private int i = 20;
// public int show(){
// return getI()+10;
// }
public int getI() {
return i;
}
}
System.out.println(two.show());//30
System.out.println(two.show2());//20
System.out.println(two.show());//40
30直接调用子类的show
40是注释后的结果 two中的show方法所以调用了父类one的show方法 父类中的getI()方法调用的还是two的方法所以返回的是20
show2()因为子类没有这个方法所以调用了父类的show2() 因为属性没动态绑定 i使用的是父类中的10 因此输出20
2、匿名内部类
interface Bell{
void ring();
}
class CellPhone{
public void alarmClock(Bell bell){
bell.ring();
}
}
CellPhone cellPhone = new CellPhone();
cellPhone.alarmClock(new Bell() {
@Override
public void ring() {
System.out.println("好好学习");
}
});
cellPhone.alarmClock(new Bell() {
@Override
public void ring() {
System.out.println("好好赚钱 ");
}
});
运行结果是 好好学习 好好赚钱
以匿名内部类作为参数 这个匿名内部类相当于 Bell bell = 匿名内部类 实现了bell接口 同时也涉及动态绑定
异常
Error 一般是JVM 内存不足 栈溢出导致的
RuntimeException 一般是运行时才出现 不一定要全部处理 一般是代码逻辑的问题
编译异常 是要求处理的不然无法编译
包装类
包装类拥有一些方法 类型转换 等等
Integer i = 1;
Integer j = 1;
Integer X = 128;
Integer Y = 128;
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
以Integer包装类为例 int 和包装类之间会自动装箱和拆箱 如果 i 范围在int的取值范围内那么 i = j 不在 i != j 因为new了一个Inreger 就如X Y ,X !=Y 但如果是跟数据类型比较那么就是比较的是值
List 有序集合
有序集合是可以元素重复的
ArrayList 不给值创建默认是10 扩容是1.5倍 指定大小就按照大小的1.5倍
Vector 则默认10 扩容是2倍 指定大小就直接2倍扩容 是加了锁的
看一遍源码流程就知道结果了
Set无序集合
无序元素不重复
HashSet底层是HashMap,根据键hash值和equals(自己实现的)来比较元素是否相同 当table>=64和链表到8时就会转为红黑树
有一个加载因子0.75 就是不会等到table满了才扩容 table达到临界值或者存放了临界值(初始12)个数据就会扩容 0.75*table
LinkedHashSet是有序的
TreeSet 可以选择构造器排序底层是TreeMap 将compare传给了TreeMap根据compare规则添加元素
Map
Map是无序的 键不能重复 值可以重复
HashMap中的数据 是Node类型K-V 放在table中 然后为了方便操作 Node中的K-V组成entry放在Set中,entry和Set是对Table中node的引用。
HashMap键可以为null 线程不安全的
HashTable 线程安全 键不能为null 底层是Entry数组 加载因子也是0.75 Table默认值是11 扩容是2倍+1
TreeMap 也是可以选择排序的选择使用不同的构造器实现compare
泛型
不能用数据类型传递要用引用类型
class yy<K,V>{
public <E> void ces(E e){
System.out.println(e.getClass());
}
public void shiYong(V v){
}
}
返回类型前加泛型才是泛型方法,在方法上带参数只是使用泛型 必须使用类创建时指定的类型。
<?> 表示所用类型
<? extends xx>表示泛型的下限 xx类及子类才可以放
<? super xx>表示泛型的上限 xx类及其父类
多线程
多线程的状态图 自己画的 7个状态
类加载
Java中将Java文件编译成.Class字节码文件然后通过加载阶段、链接阶段、初始化阶段。
1、加载阶段会通过一个类的全限定名获取这个类的二进制字节流,然后将这个字节流所代表的静态存储结构转换为方法区的进行时数据结构,在内存中生成一个Class对象作为各种数据的访问入口。
2、链接阶段分为 验证、准备、解析三个阶段。
验证 确保Class文件符合虚拟机的要求
准备 为类变量分配内存 并赋上初始值(默认值 0 或null)而final static 修饰的 也就是常量是直接赋上了值
解析 将符号引用转换为直接引用(也就是内存地址)
3、初始化阶段 通过类构造器对带有static的变量或语句进行初始化
静态变量、静态初始化块)–>(变量、初始化块)–> 构造器;如果有父类,则顺序是:父类static方法 –> 子类static方法 –> 父类构造方法- -> 子类构造方法
Mybatis
防止sql注入 将${} 换位#{} ,${}是将语句当成文本 #{} 是替代
当接口参数有多个的时候加上@Param(参数名)确保传递的参数是正确的,引用类型不用加