建议31:
在接口中不要存在实现代码,
建议32:静态变量一定要先声明
对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,
再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造
方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的
构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,
那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
建议33:不要复写静态方法
静态方法虽然不能复写,但是可以隐藏。
对象类型有两个类型:表面类型,即声明时的类型,实际类型是对象产生时的类型。
例如:Object b = new String("liang"); Object是表面类型,String是实际类型。
对于非静态方法,它是根据对象的实际类型来执行的,也就是会执行子类里面的方法。而对于静态方法来说就比较特殊了,首先静态方法不依赖实例对象,它是通过类名
访问的;其次,可以通过对象访问静态方法,如果是通过对象调用静态方法,JVM则会通过对象的表面类型查找到静态方法的入口。
建议36:使用构造代码块精炼程序(即 非静态代码块)
使用场景
1:初始化实例变量
2:初始化实力环境
建议37:构造代码会想你所想
构造代码块是为了提取构造函数的共同量,减少各个构造韩的代码块而产生的。
建议38:使用静态内部类提高封装性
Java中的嵌套类,分为两种:静态内部类和内部类
静态内部类与普通内部类的区别
普通内部类持有外部类的应用,可以访问外部类的所有属性和方法。
静态内部类则只能访问外部类的静态属性和静态方法。
静态内部类不依赖于外部类,即使外部类消亡了,静态内部类也还是存在的。
建议39:使用匿名类的构造函数
匿名函数 虽然没有名字,但也是可以有构造函数的,它用构造代码块来代替。
建议40:匿名类的构造函数很特殊
建议41:让多重继承成为现实
在java中,是可以多重实现的,不可以多重继承的。但是可以通过java的内部类,曲折的解决此问题,这要归功于内部类的一个重要特性,内部类可以继承一个与外部类无关的类,保证了内部类的独立性,正是基于
这点,多重继承才会成为可能。
建议42:让工具类不可实例化
将类的构造函数的权限设置为 private 的 并且在构造函数中抛异常。做了以上操作后,类就不可以被继承了,因为子类实例化的时候,没有可访问的父类构造函数。
建议43:避免对象的浅拷贝
java类要想实现自身的克隆需要实现 Cloneable 接口,并且调用 super.clone() 方法(Object中的方法)。
java浅拷贝(浅克隆)的规则
1:基本类型
如果是基本类型,则拷贝其值。
2:对象的引用
如果变量是一个实例对象,则拷贝地址引用,也就是说此时新拷贝出的对象与原有对象共享该对象实例变量,不受访问权限的限制。
3:String字符串
这个比较特殊,拷贝的也是一个地址,是个引用,但是在修改时,它会从字符串池(String Pool)中重新生成新的字符串,原有的字符串对象保持不变,在此我们可以认为String是一个基本类型。
建议44:推荐使用序列化实现对象的拷贝
在内存中通过字节流的拷贝来实现对象的深度拷贝,也就是把对象写到一个字节流中,再从字节流中将其读出来,这样就可以重建一个对象了,该对象与母对象之间不存在引用共享的问题,也就相
当于深拷贝了一个新对象。
建议47:在equals中使用getClass进行类型判断
在覆写equals时建议使用getClass进行类型判断,而不要使用instanceof。