如何编写工具类(下述的工厂类其实也属于工具)
方式一:
1、把工具方法做成非static方法。
2、把工具类做成单例模式
那么要调用工具方法,必须先得到工具类对象,再调用方法 如下的BeanFactory类
方式二:
1、把工具方法做成static 方法。
2、把工具类所有的构造器私有化,或者把该工具类加上abstract
这么做的目的就是为了全部是类去调用工具方法。如:java.utl.Arrays就这么做的
代码:
public class CreatInstanceDemo { public static void main(String[] args) { //java.util.Date Date dl = (Date)createInstance("java.util.Date"); System.out.println(dl.toLocaleString()); System.out.println("============================================="); Date d2 = createInstance(Date.class); System.out.println(d2.toLocaleString()); System.out.println("============================================="); // Date d3 = createInstance(Date.class,"java.util.Date"); Date d3 = BeanFactory.INSTANCE.getBean(Date.class, "java.util.Date"); System.out.println(d3.toLocaleString()); } //方案一:提供一个方法,根据传入的类的全限定名,创建一个对象,并返回 //但此方法有个弊端:每次创建出来的对象都要强制转换为目标对象 public static Object createInstance(String className){ try { Class clz = Class.forName(className); Object obj = clz.newInstance(); return obj; } catch (Exception e) { e.printStackTrace(); } return null; } //解决方案二的问题: public static <T>T createInstance(Class<T> clz){ try { return clz.newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } //但有个问题,我的需求是根据全限定来创建对象,那此时可以将方案一和方案二结合在一起 public static <T>T createInstance(Class<T> checkType,String className){ try { Class<T> clz = (Class<T>) Class.forName(className); Object obj = clz.newInstance(); //需要检查checkType是否是obj的字节码 if (!checkType.isInstance(obj)){ throw new IllegalArgumentException("对象和类型不兼容"); } return (T)obj; } catch (Exception e) { e.printStackTrace(); } return null; } }最终将工具方法独立出来:
//对象工厂,专门用来创建对象 public enum BeanFactory { INSTANCE; //为了能够使其他类也能使用该方法,我们专门把该方法抽取到ObjectFactory类中,而该类表示为工厂类,专门负责创建对象 //但工厂对象涉及到单例设计模式,防止他人多次创建,这样可减少程序的性能 public <T>T getBean (Class<T> checkType,String className){ try { Class<T> clz = (Class<T>) Class.forName(className); Object obj = clz.newInstance(); //需要检查checkType是否是obj的字节码 if (!checkType.isInstance(obj)){ throw new IllegalArgumentException("对象和类型不兼容"); } return (T)obj; } catch (Exception e) { e.printStackTrace(); } return null; } }************************************************************************************************************************************
以上用到的是一些反射的知识,这边补充下反射知识
获取class实例的几种方法:
1) 类名.class (相当于一份字节码)
2)Class.forName(String className) 根据一个类的全限定名来构建对象
3)每一个对象都有getClass()方法obj.getClass();返回对象的真实类型
###如果一个类中的构造器可以直接访问,且无参数,那么可以直接使用Class类中的newInstance方法来创建对象,Public Object new Instance();相当于 new 类名;