1、反射
(1)概念:
反射:将类的各个组成部分封装为对象,对于任何一个实体类,都能够知道这个类的属性和方法,对于任意一个对象,都能够调用它的任意方法和属性。
(2)好处:
可以在程序运行的过程中,操作这些对象。
解耦,提高可扩展性。
(3)获取Class对象的三种方法:
Class.forname(“包名.类名”);此方式用于配置文件方式,通过配置文件加载类名。
类名.class,多用于参数传递。
对象.getClass(),用于对象获取字节码对象的方式。
(4)三种方法获取Class对象:
Person类:
package pers.reflect.person;
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试类:
import pers.reflect.person.Person;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
Class c1 = Class.forName("pers.reflect.person.Person");
System.out.println("c1 = " + c1);
Class c2 = Person.class;
System.out.println("c2 = " + c2);
Person p1 = new Person();
Class c3 = p1.getClass();
System.out.println("c3 = " + c3);
System.out.println(c1==c2);
System.out.println(c2==c3);
System.out.println(c1==c3);
}
}
通过程序运行结果可以看出,不管通过哪种方式,获取的字节码文件对象是同一个。也就是说,运行期间,一个类只产生一个Class对象。
2、Class对象获取成员变量
(1)Class类的常用方法(获取Field对象):
创建Person类:
package pers.reflect.person;
public class Person {
private String name;
private int age;
public String hobby;
public String height; protected String sex; String address; public Person(){ } public Person(String name,int age){ this.name=name; this.age=age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", hobby=" + hobby + ", height=" + height + ", sex=" + sex + ", address=" + address + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
import java.lang.reflect.Field;
import pers.reflect.person.Person;
public class ReflectDemo {
public static void main(String[] args) throws SecurityException,
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Class c = Person.class;
System.out.println("getFields(),获取公共的成员变量:");
Field[] fields = c.getFields(); for (Field field : fields) { System.out.println(field); } System.out.println("getField(),获取指定的公共的成员变量:"); Field hobbyField = c.getField("hobby"); System.out.println(hobbyField); System.out.println("getDeclaredFields(),获取所有的成员变量,与修饰符无关。"); Field[] fields1 = c.getDeclaredFields(); for (Field field : fields1) { System.out.println(field); } System.out.println("获取私有的指定的成员变量"); Field nameField = c.getDeclaredField("age"); System.out.println(nameField); } }
(2)Field类的常用方法:
返回变量的类型:
返回属性的名字:
import java.lang.reflect.Field;
import pers.reflect.person.Person;
public class ReflectDemo1 {
public static void main(String[] args) {
Class c = Person.class;
System.out.println("getDeclaredFields(),获取所有的成员变量,与修饰符无关。");
System.out.println();
Field[] fields1 = c.getDeclaredFields();
for (Field field : fields1) {
System.out.println("成员变量:"+field);
System.out.println("属性的类型:"+field.getType());
System.out.println("属性的名字:"+field.getName());
System.out.println();
}
}
}
import java.lang.reflect.Field;
import pers.reflect.person.Person;
public class ReflectDemo2 {
public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Class c = Person.class;
System.out.println("getField(),获取指定的公共的成员变量:");
Field hobbyField = c.getField("hobby");
System.out.println(hobbyField);
Person p=new Person();
Object value=hobbyField.get(p);
System.out.println(value);
hobbyField.set(p, "张可可");
System.out.println(p);
System.out.println();
}
}
访问不是被public修饰的成员变量(要用暴力反射,否者无法访问):
import java.lang.reflect.Field;
import pers.reflect.person.Person;
public class ReflectDemo3 {
public static void main(String[] args) throws SecurityException,
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Class c = Person.class;
Field nameField = c.getDeclaredField("name");
nameField.setAccessible(true);//暴力反射
System.out.println(nameField);
Person p = new Person();
Object value = nameField.get(p);
System.out.println(value);
nameField.set(p, "赵晓霞");
System.out.println(p);
}
}
setAccessible(true);忽略权限修饰符的安全检查。
3、获取构造方法
package pers.reflect.Constructor;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import pers.reflect.person.Person;
public class ReflectDemo1 {
public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException,
InstantiationException, IllegalAccessException, InvocationTargetException {
Class c = Person.class;
System.out.println("getDeclaredConstructors(),获取所有的构造方法:");
Constructor[] cons = c.getDeclaredConstructors(); for (Constructor con : cons) { System.out.println(con); } System.out.println(); System.out.println("getConstructors(),获取所有的构造方法:"); Constructor[] cons1 = c.getConstructors(); for (Constructor con : cons1) { System.out.println(con); } System.out.println(); Constructor con=c.getConstructor(String.class,int.class); Object p=con.newInstance("张珊珊",12); System.out.println(p); Constructor con1=c.getConstructor();//空参数的构造方法创建Person类对象 Object p1=con1.newInstance(); System.out.println(p1); } }
4、获取成员方法
(1)常用方法:
public Method getMethod(String name, Class>… parameterTypes) 获取Public修饰的一个方法
public Method getDeclaredMethod(String name, Class>… parameterTypes) 获取所有权限的一个方法
public Method[] getMethods() 本类与父类中所有public 修饰的方法所有方法
public Method[] getDeclaredMethods() 获取本类中所有的方法
(2)应用:
package pers.reflect.person;
public class Person {
private String name;
private int age;
public String hobby;
public String height; protected String sex; String address; public Person(){ } public Person(String name,int age){ this.name=name; this.age=age; } protected void sports() { System.out.println("我爱运动"); } private void sport() { System.out.println("我不爱运动"); } public String toString() { return "Person [name=" + name + ", age=" + age + ", hobby=" + hobby + ", height=" + height + ", sex=" + sex + ", address=" + address + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void study(String name){ System.out.println(name+"爱学习"); } }
获取公共的空参的成员方法:
package pers.reflect.method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.StubNotFoundException;
import pers.reflect.person.Person;
public class reflectDemo {
public static void main(String[] args) throws SecurityException,
NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Class c = Person.class;
Method study_method = c.getMethod("study");
Person p = new Person(); study_method.invoke(p); } }
获取公共的带参数的成员方法:
package pers.reflect.method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import pers.reflect.person.Person;
public class reflectDemo {
public static void main(String[] args) throws SecurityException,
NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Class c = Person.class;
Method study_method1 = c.getMethod("study",String.class);
Person p = new Person(); study_method1.invoke(p,"Tom"); } }
获取所有的公共的方法:
package pers.reflect.method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import pers.reflect.person.Person;
public class reflectDemo {
public static void main(String[] args) throws SecurityException,
NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Class c = Person.class;
Method[] methods = c.getMethods();
for (Method method:methods){ System.out.println(method); } } }
获取方法名字:
package pers.reflect.method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import pers.reflect.person.Person;
public class reflectDemo {
public static void main(String[] args) throws SecurityException,
NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Class c = Person.class;
Method[] methods = c.getMethods();
for(Method method:methods){ System.out.println(method.getName()); } } }
获取所有的方法(忽略权限修饰符):
package pers.reflect.method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import pers.reflect.person.Person;
public class reflectDemo {
public static void main(String[] args) throws SecurityException,
NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Class c = Person.class;
Method[] methods = c.getDeclaredMethods();
for(Method method:methods){ method.setAccessible(true); System.out.println(method); } } }