一、类之间的三种关系:
1. 依赖关系(use-a)
2. 继承关系(is-a)
3. 聚合关系 (has-a)
二、Java中的方法,得到的总是参数的值拷贝。
1. 对于原始类型来说,参数是最简单的值拷贝,因而,在方法中对参数的修改无法对传参的值产生影响。
2. 对于引用类型来说,参数是对引用的一次拷贝。划重点:值拷贝。
三、Java中的转型问题。
1. 基本类型的转型(无数据丢失)。
a. byte -> short -> int -> long
b. byte -> short -> int -> double
c. char -> int -> long
d. char -> int -> double
2. 基本类型的转换(有数据丢失)
a. long -> float
b. int -> float
c. long -> double
转换规则: double > float > long > int 。
3. 基本类型的强制转换。(type) value。一般有数据丢失情况存在。
4. 引用类型的转换。向上,向下是相对于被操作的引用变量的类型而言的。转换前是父类类型,转换后是子类类型,则成为向下转型,否则成为向上转型。向上转型是一个自动的过程。
a. 向下转型。将父类类型的引用强制转换并赋值给子类类型的引用,称为向下转型。向下转型可以获得子类的方法列表。限制,被向下转型的子类,必须是目标子类的实例,否则会报错。
b. 向上转型。子类类型的对象被赋值给父类类型的引用变量,称为向上转型。向上转型存在方法的丢失现象。方法列表中只存在父类的方法列表。
c. 继承链中对象方法的调用的优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)
四、重写。
a. 重写是子类对父类中允许访问的方法的实现过程进行重写,其方法名,形参不能改变,返参类型和父类相同或者是父类的返参类型的子类,子类方法的访问权限不能小于父类方法的访问权限。
五、重载
a. 重载是在同一个类中,多个方法的方法名相同而参数不同的一种规则。
六、多态和动态绑定。
a. 多态。
在java中,一个父类类型的变量,既可以引用一个父类类型的对象,也可以引用一个子类类型的对象,称之为多态,对象引用变量是多态的。
b. 动态绑定。
1.如果被调用的方法是private、static或者final方法,则在编译期间,编译器就可以准确的直到调用了哪个方法,那么这种方法绑定称之为静态绑定。与之相对的是,有些方法的调用需要根据其运行时的实际对象来确定,这种绑定称之为动态绑定。
2.方法的动态绑定,依照如下规则:
this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
3.由于方法动态绑定的原因,每次方法执行时都需要大量的搜索,因而虚拟机为每个类都预先生成了一个方法表,以提高性能。
七、自动装箱和拆箱
1. 自动装箱。编译器自动地将原始类型的值转换为对应包装器的对象类型。byte、short、char、int、long、float、double、boolean对应的包装器类为Byte、Short、Character、Integer、Long、Float、Double和Boolean。
2. 自动拆箱。编译器自动的将包装器的对象类型转换为原始类型的值。
3. 注意事项:
a. 尽量避免大量的自动装箱和自动拆箱的情况出现,例如在循环中的自动装箱和自动拆箱,需要生成大量的无用的包装类型对象。
b. 自动装箱、自动拆箱遇到重载时,首先会试图调用无需自动装箱拆箱的方法,然后才是需要自动装箱的方法。
c.Integer的缓存。对于-128到127之间的数字,Integer对其进行了缓存,在自动装箱的ValueOf方法调用的时候,会将缓存的Integer对象直接返回给程序,因而,对于-128到127的数字,同时发生了自动装箱时候,得到的是同一个对象。但是,对于Integer构造函数构造的对象来说,永远都是不相等的。
d. 混乱的使用原始类型和包装类型,可能造成空指针异常。对于static Integer count;其默认初始换值是null。而static int count的默认初始化值则是0。
f. 含有算术运算的过程,会发生自动拆箱操作。
八、可变参数方法
public void method(String... args)
九、== 和 equals() 方法
1. ==
1. 比较基本类型的值。
2. 比较对象在内存中的地址是否相同。
2. equals方法
1. 一般来说,首先比较两个对象的内存地址是否相同,相同直接返回true。
2. 对对象的真实值进行比较,如果真实值相同,那么就返回true,否则返回false。
十、 内部类。
1.内部类分类。
a.成员内部类。
b.静态内部类。
c.局部内部类。
d.匿名内部类。
2.成员内部类。
a.成员内部类可以直接访问外部的私有方法和属性。
b.当成员内部类的属性和方法与外部类的属性和方法名字相同时,可以通过Outer.this.name来访问外部类的属性或者方法。
c.成员内部类不能有static的方法和属性。
d. 必须先创建外部类,才可以创建内部类。
c. 外部类可以通过内部类的对象来访问内部类的私有变量和方法。
3.局部内部类。局部内部类是定义在方法中的内部类。
a.局部内部类不能有public或者private等访问修饰符。
b.局部内部类可以访问final修饰的局部变量。
4. 匿名内部类。匿名内部类是直接生成了对象的无名类。
5. 静态内部类。
a、创建静态内部类方式:Outer.Inner inner = new Outer.Inner();静态内部类不依赖于外部类。
b、外部类可通过内部类的对象调用内部类的私有成员变量或方法。
c、静态内部类访问外部类的静态成员变量或方法必须是静态的。
d、静态内部类中可定义静态的成员变量和方法。
e、外部类可以创建静态内部类的实例,即使是私有的;并可通过内部类的实例访问内部类的成员变量和方法,即使是私有的。
f、单利模式中的静态内部类模式。
十一、反射。
反射是在运行时访问类的构造方法,属性,静态变量,方法等的能力。在运行时对类的属性等进行访问和修改的能力。
1.获取数组的类型。obj.getClass().getComponentType()。
2.动态生成数组。Array.newInstance(Class<?>,length),返参为一个数组实例对象。
3.反射中的一些常用类Array、Field、Method、Constructor、Modifier等。
4.java创建对象的几种方法:
a.new关键字。
b.newInstance()方法。
c.clone()方法。
d.反序列化。
十二、动态代理。
1.静态代理的问题。有多少个需要代理的类,就需要有多少个静态代理类,这会造成类爆炸。
2.jdk动态代理。jdk动态代理与java.lang.reflect包内的三个类有关:
a.InvocationHandler类。
b.Method类。
c.Proxy类。
3.创建一个动态代理的一般步骤:
a.创建一个InvocationHandle实现类,并实现其invoke方法。
b.创建被代理的类的对象实例。
c.通过Proxy类的newProxyInstance()方法实例化一个代理对象。传参分别为被代理的ClassLoader和Interfaces以及a中handle实现类的实例。
d.通过Proxy类的实例调用被代理类实例的方法,即可实现对被代理类方法的代理。