反射
根据自己的理解就是利用反射可以获取想要类的所有东西,包括,方法,成员变量等等。可见它的地位非比寻常。了解反射前,要知道Class类,因为反射依赖于这个类。class表示文件的字节码文件,而类字节码文件就是在描述一个类,描述类的成员变量,成员函数,构造函数。Class类中有获取成员变量的,成员函数,构造函数的函数。分别是getField(String name),getMethod(),getConstructor(),使用起来也是很方便。获取Class的三种方式也是重中之重,主要也就是三种方式。第一种:类名.class,第二种:对象.class,第三种:class.forNsmr("类全路径")。下面是三种反射方式的案列:
package cn.str; public class ClassDemo { public static void main(String[] args) { // 类名.class Class clazz=String.class; System.out.println("全名"+clazz.getName()); System.out.println("简名"+clazz.getSimpleName()); System.out.println(); // 对象.getClass() Class clazz2 = "杰克".getClass(); System.out.println("全名"+clazz2.getName()); System.out.println("简名"+clazz2.getSimpleName()); System.out.println(); // class.forName() try { Class clazz3 = Class.forName("java.lang.String"); System.out.println("全名"+clazz3.getName()); System.out.println("简名"+clazz3.getSimpleName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
以上是反射的集中常见的方式,建议大家选择使用第三种方式,好处就是只需要知道类的全路径,就可以获取该对象,简单方便。而且在实际开发中,你也会经常会碰到第三种方式。对于前两种方式,可以达到遇到这种方式,可以看得懂就可以。再接下来,着重介绍利用反射获取实体类中的变量,方法,构造函数。首先,利用反射获取实体类中的所有的构造函数。先附上一个实体类:
package cn.str; public class Person { private int age; public String name; public Person() { super(); } public Person(int age, String name) { super(); this.age = age; this.name = name; } public Person(String name) { super(); this.name = name; } public Person(int age) { super(); this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
获取所有的构造函数:Class中获取所有构造方法(包括私有的):getDeclaredConstructors( ),指定的构造函数getConstructor(参数类型Class)还有获取私有的构造和方法,这里不做详细介绍,知道有这个方法即可,代码如下:
package cn.str; import java.lang.reflect.Constructor; public class ClassDemo4 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException { Class<?> class1 = Class.forName("cn.str.Person"); // 获取实体类中所有的构造方法 Constructor<?>[] declaredConstructors = class1.getDeclaredConstructors(); for (int i = 0; i < declaredConstructors.length; i++) { System.out.println(declaredConstructors[i]); } System.out.println("=================="); // 获取指定的构造函数 Constructor<?> constructor = class1.getConstructor(int.class); System.out.println(constructor); System.out.println("=================="); } }
接下来是利用反射获取成员变量,获取成员变量的方法有getFields( ) :获取所有的公共成员变量,getDeclaredFields( ):获取所有的成员变量(包括私有的),getField(String XX):根据变量名获取指定的成员变量,getDeclareFields(String XX):根据变量获取指定的成员变量,包括私有的。代码如下:
package cn.str; import java.lang.reflect.Field; public class ClassDemo5 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException { Class<?> class1 = Class.forName("cn.str.Person"); // 获取所有的公共成员变量名 Field[] fields = class1.getFields(); for (int i = 0; i < fields.length; i++) { System.out.println(fields[i]); } System.out.println("==========="); // 获取所有的成员变量(包括私有的) Field[] fields2 = class1.getDeclaredFields(); for (int i = 0; i < fields2.length; i++) { System.out.println(fields2[i]); } System.out.println("==========="); // 获取指定的公共成员变量 Field field = class1.getField("name"); System.out.println(field); System.out.println("==========="); // 获取指定的变量(包括私有的成员变量) Field field2 = class1.getDeclaredField("age"); System.out.println(field2); Field field3 = class1.getDeclaredField("name"); System.out.println(field3); } }
如果通过反射获取变量并且为变量赋值,且变量是私有的,则利用setAccessible(true),下面介绍获取成员方法的示例,代码如下:
Class<?> forName = Class.forName("cn.str.Person"); Person p = (Person) forName.newInstance(); Method method = forName.getMethod("setName", String.class); Object invo = method.invoke(p, "人"); System.out.println(p); System.out.println(invo); System.out.println(method);