1.数据库的连接池
由于创建连接的代价是很高的, 我们每次访问数据库都重新创建连接的话是非常消耗性的.
我们可以再程序启动的时候先创建出一些连接, 放在一个集合中, 访问数据库的时候从集合中获取, 使用结束再放回集合中.
这样做只是在程序启动的时候消耗性能去创建连接, 每次访问数据库的时候都是从内存中获取连接, 可以大大提升效率.
注意事项:
由于池中增删非常频繁, 使用集合LinkedList效率较高
集合中所有连接都被占用时创建新连接, 但需要注意连接总数
使用组合模式/动态代理处理释放连接的方法, 当运行close方法时, 将连接放回池中
2.反射机制
(1)反射语句的特点:反射是Java程序开发语言的特征之一。它允许动态地发现和绑定类、方法、字段,以及所有其他的由语言所产生的元素。
(2)反射机制提供的功能:
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法。通过反射甚至可以调用到private的方
(3)Java反射所需要的类并不多,主要有java.lang.Class类和java.lang.reflect包中的Field、Constructor、Method、Array类。
1.Class类:Class类的对象表示正在运行的 Java 应用程序中的类和接口。
(1)调用Object类的getClass()方法来得到Class对象,这也是最常见的产生Class对象的方法。例如,
MyObject x=new MyObject();
Class c1 = x.getClass();
(2)使用Class类的forName()静态方法获得与字符串对应的Class对象。Class c2=Class.forName("java.lang.String");
注意:参数字符串必须是类或接口的完全限定名。
(3)使用类型名.class获取该类型对应的Class对象。例如,
Class cl1 = Manager.class;
Class cl2 = int.class;
Class cl3 = double[].class;
2. Field类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射. 字段可能是一个类属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。
3. Constructor类:提供关于类的单个构造方法的信息以及对它的访问权限。它封装了反射类的构造方法。
4. Method类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。它是用来封装反射类方法的一个类。
5. Array类:提供了动态创建数组和访问数组的静态方法。该类中的所有方法都是静态方法
注意:Class类是Java反射的起源,针对任何一个你想探勘的类,只有先为它产生一个Class类的对象,接下来才能通过Class对象获取其他想要的信息。
(4)获取类型信息
要在运行时获取某个类型的信息,需先获取这个类型所对应的Class对象,然后调用Class类提供的相应方法来获取。
(1)获取指定类对应的Class对象
Class clazz = Class.forName("java.util.ArrayList");
(2)获取指定类的包名clazz.getPackage()获取此Class对象所对应的实体所在的包的信息描述类java.lang.Package的一个对象。
String packageName = clazz.getPackage().getName();
(3)获取指定类的修饰符
通过Class对象的getModifiers()方法可以获取此Class对象所对应的实体的用整数表示的类修饰符值。
int mod = clazz.getModifiers();
String modifier = Modifier.toString(mod);
String str = Clazz.getModitiers().toString();
(4)获取指定类的完全限定名
className = clazz.getName();
(5)获取指定类的父类
superClazz = clazz.getSuperclass();
(6)获取指定类实现的接口
通过Class对象的getInterfaces()方法可以获取此Class对象所对应的实体实现的所有接口的Class对象数组。Class[] interfaces = clazz.getInterfaces();
(7)获取指定类的成员变量
通过Class对象的getFields()方法可获取此Class对象所对应的实体的所有public字段(成员变量)。如果要获取所有字段,可以使用getDeclaredFields()方法。
注:方法返回的是java.lange.reflect.Field类的对象数组。Field类用来代表字段的详细信息。通过调用Field类的相应方法可以获取字段的修饰符、数据类型、字段名等信息。
(8)获取类的成员方法
通过Class对象的getMethods()方法获取到的是该Class对象所对应的实体的所有public成员方法。如果要获取所有成员方法,可以使用getDeclaredMethods()方法。
Method[] methods = clazz.getDeclaredMethods();
(9)获取类的构造方法
通过Class对象的getConstructors()方法可获取该Class对象所对应的实体的所有public构造方法。如果要获取所有的构造方法,可以使用getDeclaredConstructors()方法。
Constructor[] constrcutors = clazz.getDeclaredConstructors();
例子:获取构造方法用数组的形式
for (Constructor constructor : constrcutors) {
String name = constructor.getName();
String modifier = Modifier.toString(constructor.getModifiers());
System.out.print(" " + modifier + " " + name + "(");
Class[] paramTypes = constructor.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if(i > 0){ System.out.print(", "); }
if(paramTypes[i].isArray()){
System.out.println(paramTypes[i].getComponentType().getName() + "[]");
}else{
System.out.print(paramTypes[i].getName());
}
}
System.out.println(");");
}
例子:用数组的形式获取
java.lang.reflect.Field[] fields =t.getDeclaredFields();
for(java.lang.reflect.Field f:fields){
String modifier = Modifier.toString(((Member) f).getModifiers());
String name = f.getName();
Class type = f.getType();
if(type.isArray()){
System.out.println(modifier+" "+type.getComponentType().toString()+"[] "+name);
}
System.out.println(modifier+" "+type.toString()+" "+name);
}
(5)创建对象
(1)使用无参构造方法
如果要使用无参的构造方法创建对象,只需调用这个类对应的Class对象的newInstance()方法。
Class c = Class.forName("java.util.ArrayList");
List list = (List) c.newInstance();
需要注意的是:如果指定名称的类没有无参构造方法,在调用newInstance()方法时会抛出一个NoSuchMethodException异常。
(2) 使用带参数的构造方法
要使用带参数的构造方法来创建对象,可以分为如下3个步骤来完成。
第1步 获取指定类对应的Class对象。
第2步 通过Class对象获取满足指定参数类型要求的Constructor对象。
第3步 调用指定Constructor对象的newInstance方法,传入对应的参数值,创建对象。
(6)调用方法
使用反射可以取得指定类的指定方法的对象代表,方法的对象代表就是java.lang.reflect.Method类的实例,通过Method类的invoke方法可以动态调用这个方法。
public Object invoke(Object obj, Object... args) throws IllegalAccessException,IllegalArgumentException, InvocationTargetException
该方法的第一个参数是一个对象类型,表示要在指定的这个对象上调用这个方法
第二个参数是一个可变参数,用来给这个方法传递参数值;
invoke方法的返回值用来表示动态调用指定方法后的实际返回值。
注意:若要通过反射调用类的某个私有方法,可以在这个私有方法对应的Method对象上,先调用setAccessible(true)来取消Java语言对本方法的访问检查,然后再调用invoke方法来真正执行这个私有方法。
(7)访问成员变量的值
使用反射可获取类的成员变量的对象代表,成员变量的对象代表是java.lang.reflect.Field类的实例,可以使用它的getXXX方法来获取指定对象上的值,也可以调用它的setXXX方法来动态修改指定对象上的值,其中的XXX表示成员变量的数据类型。
(8) 操作数组
数组也是一个对象,可以通过反射来查看数组的各个属性信息。
(9) Properties文件的处理
Java中的properties文件是一种配置文件,主要用于表达配置信息,文件类型为*.properties,格式为文本文件,文件的内容是格式是“键=值”的格式,也就是说文件的每一行都是先定义一个键名,然后等于号后面是值,在properties文件中,可以用“#”来作注释
JDK 中的 Properties 类存在于包java.util 中,该类继承自 Hashtable ,主要方法包括:
(1)getProperty(String key):用指定的键在此属性列表中搜索属性。也就是通过参数 key ,得到key所对应的 value。
(2)load(InputStream inStream) :从输入流中读取属性列表(键和元素对)。通过对指定的文件进行装载来获取该文件中的所有键-值对,以供getProperty(String key) 来搜索。
(3)setProperty(String key, String value):调用Hashtable的方法put 。来设置“键-值”对。
(4 )store(OutputStream out, String comments):以适合使用load方法加载到Properties表中的格式,将此Properties表中的属性列表(键和元素对)写入输出流。
(5)clear ():清除所有装载的“键-值”对.