一、为什么我要写高效的Java编程的文章呢
1⃣️、我认为在我们工作的经验越来越多的时候,可能回过头看看自己曾经写过的代码是很丑的,所以多学下好的编码习惯,有利于bug越来越少。
2⃣️、当你想重构代码的时候,我认为也会用的到
二、用静态工厂方法代替构造器
对于类而言,为了让客户端获取它自身的一个实例的时候
方法1⃣️、提供一个公有的构造器
方法2⃣️、提供一个公有的静态工厂方法,它只是返回类的实例的静态方法,和设计模式中的工厂方法模式不同。
代码如下:
上面的代码就把一个来自Boolean的简单示例,这个方法就把一个boolean的基本数据类型转换成了一个Boolean对象的引用。
三、给客户端提供的静态方法的优势
1⃣️、他们有名称:
a、如果构造器的参数本身没有确切地描述正被返回的对象,那么用静态工厂的方法更实用,产生的客户端代码更容易易读。
b、比如:BigInteger.probablePrime的静态工厂方法来表示,显然更为清楚。当一个类需要多个带有相同的签名的构造器时,就用静态工厂方法来代替构造器,并且仔细选择名称以便突出静态工厂方法之间的区别。
2⃣️、不必每次调用它们的时候都创建一个新对象
a、这样可以使得不可变类可以使用预先构建好的实例,或者将构建好的实例缓存起来,进行重复利用,从而避免不必要的重复对象,上面的例子就是它从来不创建对象,可以提升性能,这种方法类似于享元设计模式。
b、静态工厂方法能够为重复的调用返回相同的对象,这样有助于类总能严格控制在某个时刻哪些实例存在,这种类被称作为实例控制的类,实例受控使得类可以确保它是一个Singleton或者是不可实例化的,它还使得不可变的值类可以确保不会存在两个相等的实例,即当且仅当a=b时,a.equals(b)才为true.这是享元设计模式的基础,枚举类型也保证了这一点。
3⃣️、它们可以返回原返回类型的任何子类型的对象
a、这样我们在选择返回对象的类时就有了更大的灵活性。可以使用API返回对象,这样可以变得非常简洁,这项技术可以适用于基于接口的框架,因为在这种框架中,接口为静态工厂方法提供了自然返回类型。
b、在java8之前,接口不能有静态方法,接口Type的静态工厂方法被放在一个名为Types的不可实例化的伴生类中。例如:在Collections集合中有45个实现类可以实现,几乎所有这些实现都通过静态工厂方法在一个不可实例化的类中导出,所有返回的对象都是非公有的。
c、从jdk8之后,接口中可以包含静态方法,也不会给接口提供一个不可实例话的伴生类。可以把这种类中的许多公有的静态成员应该放到接口中去。但是有必要将这些静态方法背后的大部分实现代码单独放到一个包即私有的类中,因为在jdk8中仍要求接口的所有静态成员都必须是公有的。
d、在jdk9中允许接口有私有的静态方法,但是静态域和静态成员类仍然需要是公有的。
4⃣️、所返回的对象的类可以随着每次调用而发生变化,这取决于静态工厂方法的参数值
a、只要是已经声明的返回类型的子类型,都是允许的,返回对象的类也可能随着发行版本的不同而不同。
5⃣️、方法的返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在。
a、这种灵活的静态工厂方法构成了服务提供者框架的基础,比如jdbc的API。服务提供者框架:多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把它们从多个实现解耦出来。
b、服务提供者框架中有三个重要的组件:
服务接口:这是提供者实现的
提供者注册API:这是提供者用来注册实现的
服务访问API:这是客户端用来获取服务实例的。
c、服务访问API是客户端用来指定某种选择实现的条件,如果不是这样操作的话,API就会返回默认实现的一个实例,或者允许客户端遍历所有可用的实现。服务访问API是灵活的静态工厂,它构成了服务提供者框架的基础,可以返回比提供者需要更丰富的服务接口,这就是桥接模式。
d、服务提供者接口是可选的,表示产生服务接口至实例的工厂对象,如果没有服务提供者接口,实现就是通过反射的方式来实现的。但是JDBC中,Connection就是其服务接口的一部分,DriverManager.registerDriver是提供者注册API,DriverManager.getConnection是服务访问API,Driver是服务提供者的接口。
e、依赖注入可以可以看作是一个强大的服务提供者。
f、在Java 6版本开始,Java提供了一个通用的服务提供者框架java.util.ServiceLoader。
四、给客户端提供的静态方法的劣势
1⃣️、类如果不包含公有或者受保护的构造器,就不能被子类化。
2⃣️、程序员很难发现它们,对于提供了静态工厂方法而不是构造器的类来说,要想查明如何实例化一个类是非常困难的。
明天见~~