java创建对象的几种方式(重要):
(1) 用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法。
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。
关于构造函数
第一个规则:子类的构造过程中,必须调用其父类的构造方法。一个类,如果我们不写构造方法,那么编译器会帮我们加上一个默认的构造方法(就是没有参数的构造方法),但是如果你自己写了构造方法,那么编译器就不会给你添加了,所以有时候当你new一个子类对象的时候,肯定调用了子类的构造方法,但是如果在子类构造方法中我们并没有显示的调用基类的构造方法,如:super(); 这样就会调用父类没有参数的构造方法。
第二个规则:如果子类的构造方法中既没有显示的调用基类构造方法,而基类中又没有无参的构造方法,则编译出错,所以,通常我们需要显示的:super(参数列表),来调用父类有参数的构造函数,此时无参的构造函数就不会被调用。
class People {
String name;
public People() {
System.out.print(1);
}
public People(String name) {
System.out.print(2);
this.name = name;
}
}
class Child extends People {
People father;
public Child(String name) {
System.out.print(3);
this.name = name;
father = new People(name + ":F");
}
public Child() {
System.out.print(4);
}
}
这是一个巨大的命题,涉及到效率,要结合JVM来考虑更好理解。还是先从理论说,再结合几个定点实例。
1. 构造器的方法
最基本的创建实例的方法。
2. 静态工厂方法和抽象工厂方法
因为静态工厂方法在扩展的时候违背了封闭原则,所以有了抽象工厂方法。
3. 建造者模式
建造者模式是从重叠构造器(构造器的不断重载)和JavaBeans(setter模式)模式演化过来。
4. 单例模式
单元素的枚举类型已经成为实现Singleton的最佳方法
5. 隐式地创建对象
这儿主要是涉及到String类型,自动拆装箱。
6. 消除过期的对象引用
防止内存泄露(Google Heap Profiler剖析工具)。
7. 终结方法
显示的终止方法通常与try-finally结构结合起来时候,以确保及时终止。典型引用是显示可重入锁
8. 应用举例
数据库连接池和线程池是静态工厂方法的应用。
数据库连接池生命周期
数据库每个读写操作需要一个连接。数据库连接调用流如下图:
调用流程为:
- 应用数据层向DataSource请求数据库连接
- DataSource使用数据库Driver打开数据库连接
- 创建数据库连接,打开TCP socket
- 应用读/写数据库
- 如果该连接不再需要就关闭连接
- 关闭socket
容易推断出打开/关闭数据库连接是开销很大的操作。PostgreSQL为每个客户端连接产生一个分离的OS进程,因此高频率地打开/关闭数据库连接会使数据库管理系统压力增大。
重用数据库连接最明显的原因是:
- 减少应用程序和数据库管理系统创建/销毁TCP连接的OS I/O开销
- 减少JVM对象垃圾