灵感来自effective java
关于对象,是java的核心,如何有效的创建其实是一个值得关注的地方。
1.静态工厂:这是一个值得关注的,并且应该时刻考虑的方法。
优点:1.他是有名字的,这个是如何作为一个优势?假设在一个别人写的类有好几个构造函数,你应该使用哪个?哪个才是最佳的?这时候要是有一个名字就好了,但是普通的构造都是一样的名字。静态构造可以完美解决。2.可以控制对象构建,普通的构造函数只是返回一个本对象,并不能对对象作出控制,比如静态工厂结合私有构造,就可以控制构建对象的数量,也可以把对象构建缓冲池,来进行对象的复用。还有一个技巧,假如参数传递的一致就返回同一个对象。这样对象就可以使用==来比较是否相等了,这在程序优化的时候也未尝不可。3可以屏蔽构建的类返回一个父类型或者是父接口类型,这样做有效的屏蔽细节。4.简化构造,去掉了new的繁琐操作。
缺点:没有公有构造,就不能被子类化,不能突出这是一个构造,因为就是一个普通方法。
2.多个参数问题:当你有多个参数传递的时候,是使用什么方法,减少错误?
1.使用重叠的构造,也就是说根据情况,建立多个含参构造函数。这样可以根据不同的构造函数来构造。但是实在太多了!
2使用javabeans ,使用set和get。但是你有没有想过这样就把对象构造前移了,你可能构造出来的对象不能用,也无法确定那个属性是需要的,哪个属性是不需要的。pass
3.使用builder,构造器就是在你要构造的对象内部建立一个builder内部类专门来构造对象,使用多个设置参数方法,设置属性,然后在使用build构造对象,把对象属性全部拷贝到对象中去。这是结合了前两种的有效方法。
3构建单一对象:也就是单例的,在有了泛型之后,enum Obj{INSTANCE,。。。}成了一个构建单例非常有效的方法。
4.创建不必要的对象,实际上就是适当的时机使用缓存,什么时候使用?当对象的创建是重量级,比如数据库连接,另一种就是对象使用时频繁的,比如Android中的消息通讯的消息,生命周期短,但是需要大量的对象。
还有一个需要关注的就是基本数据类型和String,以前一直疑问他们是否都有缓存,实际上都有,都是在一个常量池中,程序中所有使用到的只有一个,这也就涉及到String是一个final的,不可以变的,一旦要改变就会失效,重新创建。
5内存泄露,关于java中有无内存泄露的问题,这个在android中Context由于生命周期在activity中一旦activity消亡了,但是Conetxt没有释放就会有内存泄露,这样的内存泄露就是指有保持了该对象的引用,而不释放,这主要是在有一定生命周期的对象上尤其要注意。
tip:这里提到一个如何判断引用的方法,垃圾回收器怎么判断?有人说是引用计数器,但是这个是无法解决循环指针的,也就是两个对象保持对方的引用,这样的话都不会释放,但是确实这两个对象都是没有的。实际上是使用了根搜索算法,这个是根据一定的规则判断对象是否在root引用连里面,假如没有就说明,不可能在利用到该对象了。这些规则包括:栈,静态属性引用,常量引用,和本地方法引用。
还有一个就是关于引用:强引用,软引用,弱引用,虚引用。这里面主要的区分点就是这几个对象是和gc紧密联系的,强引用是不会回收的,软引用在内存紧张时候回收,弱引用在垃圾回收的时候回收,虚引用是一定会回收的,和弱引用的区别就是弱引用还可以使用,虚引用对程序员不可见。