1、关于包装类的缓存机制
两种浮点数类型的包装类 Float,Double 并没有实现缓存机制。
对应源码:
拆装箱
都是调用了包装类的方法:valueOf(基本转包装)、xxxValue(包装转基本)
注意char
char在Java中占用
2个字节
关于静态方法和非静态成员之间的调用
静态方法属于类,非静态成员属于对象实例,静态方法是在类加载的时候就产生了,而非静态成员是在对象实例化之后才产生的
【实例方法】就是指非静态的方法
静态方法,只能访问静态成员(变量及方法)
总结重载和重写
重载:方法名必须相同,方法的返回值、修饰符、参数个数、参数类型可以不同(参数列表必须修改)。(重载是根据传入的参数不同,方法的处理也不同)
重写:方法名、参数个数、参数类型(参数列表)必须相同,返回值、异常范围<=父类的该方法,修饰符>=父类。 如果⽗类⽅法访问修饰符为 private/final/static 则⼦类就不能重写该⽅法。(因为方法体不同,所以处理不同)
两同两小一大
注意:重写时如果返回类型是 void 和基本数据类型,则返回值重写时不可修改
关于面向对象
封装:针对的是类的属性
继承:⼦类拥有⽗类对象所有的属性和⽅法(包括私有属性和私有⽅法),但是⽗类中的私有属性和⽅法⼦类是⽆法访问,只是拥有
关于对象引用和对象实例
对象实例在堆内存中,对象引用指向对象实例(对象引用存放在栈内存中)
对象的相等和引用相等的区别:
对象的相等一般比较的是内存中存放的内容是否相等。
引用相等一般比较的是他们指向的内存地址是否相等。
== 运算符比较的是字符串的引用是否相等。equals 方法比较的是字符串的内容
接口
接口中的成员变量只能是
public static final
类型的,不能被修改且必须有初始值,而抽象类的成员变量默认 default,可在子类中被重新定义,也可被重新赋值(static修饰的静态内容,实例共享;final修饰不可变的内容)
Java中子类能够继承父类的private属性或方法吗
子类继承父类,子类拥有了父类的所有属性和方法。程序验证,父类的私有属性和方法子类是无法直接访问的。当然私有属性可以通过public修饰的getter和setter方法访问到的,但是私有方法不行。
多态
多态的使用:当调用子父类同名同参数方法时,实际调用的是子类重写父类的方法
Person p2 = new Man();
简称:编译时,看左边;运行时,看右边。
“看左边”:看的是父类的引用(父类中不具备子类特有的方法)
“看右边”:看的是子类的对象(实际运行的是子类重写父类的方法)
对象的多态性:只适用于方法,不适用于属性(编译和运行都看左边)——也就是只能调用父类的属性(有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。)
想要调用用子类特有的属性和方法:向下转型
a instanceof A:判断对象a是否是类A的实例
举例://问题1:编译时通过,运行时不通过 //举例一 // Person p3 = new Woman(); // Man m3 = (Man)p3; //举例二 Person p4 = new Person(); Man m4 = (Man)p4; //问题二:编译通过,运行时也通过 Object obj = new Woman(); Person p = (Person)obj;
注意:
值传递与引用传递
值传递 :方法接收的是实参值的
拷贝
,会创建副本。
引用传递 :方法接收的直接是实参所引用的对象在堆中的地址
,不会创建副本,对形参的修改将影响到实参。
举例:
a、b 相当于 num1、num2 的副本
**Java 只有值传递**
仍然是值传递,只不过传递的值是实参的地址
swap 方法的参数 person1 和 person2 只是拷贝的实参 xiaoZhang 和 xiaoLi 的地址
总结:
Java 中将实参传递给方法(或函数)的方式是 值传递 :如果参数是基本类型的话,很简单,传递的就是基本类型的字面量值的拷贝,会创建副本。如果参数是引用类型,传递的就是实参所引用的对象在堆中地址值的拷贝,同样也会创建副本。
关于rpc协议
参考博客: rpc协议
动态代理
一、JDK动态代理机制
动态代理步骤:
创建接口
得到实现这个接口的实现类(被代理类)
新建一个实现了InvocationHandler接口的实现类(代理类),并重写其invoke方法,主要用于自定义对代理类方法的扩展
创建一个代理工厂类,通过getProxy方法得到目标被代理类的代理对象
![在这里插入图片描述](https://img-blog.csdnimg.cn/93bf101382ef44b29f7a2d5e5b213e60.png
当我们的动态代理对象调用原生方法的时候,最终实际上调用到的是 invoke() 方法,然后 invoke() 方法代替我们去调用了被代理对象的原生方法
二、CGLIB动态代理机制
步骤:
添加CGLIB的依赖
定义一个被代理类
自定义一个实现了MethodInterceptor的方法拦截器,并重写intercept方法
创建工厂类,并在其中创建一个动态代理增强类Enhancer的对象,通过调用enhancer的create方法创建动态代理类
总结:
JDK的只能代理实现了接口的类,或者直接代理接口,而CGLIB可以代理没有实现任何接口的类
BigDecimal
常用方法:
加——add、减——subtract、乘——multiply、除——divide、比较——compareToBigDecimal a = new BigDecimal("1.0");