反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
文中所使用的Person.class附于最后
package cn.my.Reflect;
/**
* 反射:就是通过class文件对象,去使用该文件的成员变量、构造方法使用成员变量、构造方法。
* 以前使用成员变量、构造方法使用成员变量、构造方法:
* >Person p = new Person;
* >通过p来使用
*
* 现在使用成员变量、构造方法使用成员变量、构造方法:
* >要想这样使用,首先你必须得到class文件对象,其实就是得到Class类对象
*
* Class 类:
* >成员变量 Field
* >构造方法 Constructor
* >成员方法 Method
* 获取Class文件对象的方式:如下代码中三种方式。
*
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
//方式一
Person p = new Person();
Class c = p.getClass();
Person p2 = new Person();
Class c2 = p2.getClass();
System.out.println(p==p2);//false
System.out.println(c==c2);//true
//方式二
Class c3 = Person.class;
//int.class;
//String.class;
System.out .println(c==c3);//true
//方式三
//ClassNotFoundException,找类时要全路径,带包名
// Class c4 =Class.forName("Person");
// System.out.print(c==c4);//报错
//cn.my.Reflect.Person
Class c4 =Class.forName("cn.my.Reflect.Person");
System.out.print(c==c4);//true
}
}
一般使用选择: 项目开发:方式三:方式三是一个字符串,而不是一个具体的类名。这样可以把这样的字符串配置到配置文件中。
通过反射获取构造方法并使用
获取无参构造方法
package cn.my.Reflect_02;
import java.lang.reflect.Constructor;
/*
* 通过反射获取构造方法并使用
*/
public class ReflectDemo {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("cn.my.Reflect_01.Person");
// /*获取构造方法
// *public Constructor[] getConstructors();拿到所有公共构造方法
// *public Constructor[] getDeclaredConstructors();拿到所有的构造方法
// */
// Constructor[] cons = c.getConstructors();//拿到所有公共构造方法
// Constructor[] cons = c.getDeclaredConstructors();//拿到所有的构造方法
// for(Constructor con : cons) {
// System.out.println(con);
// }
//获取单个构造方法
/*public Constructor getConstructor(Class<?>... parameterTypes)
* 参数表示是:你要获取的构造方法的构造参数个数和数据类型的class字节码文件对象
*/
Constructor con = c.getConstructor();//返回的构造方法对象
//public T newInstance(Object... initargs)
//使用此Constructor对象表示的构造方法来创建该构造方法的声明类的新实例,并用户指定的初始化参数初始化该实例。
Object obj = con.newInstance();
System.out.println(obj);
}
}
反射获取带参构造器并使用
package cn.my.Reflect_02;
import java.lang.reflect.Constructor;
/*
* 需求:通过反射去获取该构造方法并使用:
* public Person(String name, int age, String address)
*/
public class ReflectDemo2 {
public static void main(String[] args) throws Exception{
//获取去字节码文件对象
Class c = Class.forName("cn.my.Reflect_01.Person");
//获取带参构造器
//public Constructor getConstructor(Class<?>... parameterTypes)
Constructor con = c.getConstructor(String.class, int.class, String.class);
//通过带参构造方法对象创建对象
//public T newInstance(Object... initargs)
Object obj = con.newInstance("林青霞", 27 , "北京");
System.out.println(obj);
}
}
反射获取并使用私有的构造方法
package cn.my.Reflect_02;
import java.lang.reflect.Constructor;
import javax.print.attribute.standard.PrinterLocation;
/*
* 需求:通过反射获取私有构造方法并使用
* private Person(String name){}
*/
public class ReflectDemo3 {
public static void main(String[] args) throws Exception {
Class c = Class.forName("cn.my.Reflect_01.Person");
//Constructor con = c.getConstructor(String.class);报错NoSuchMethodException,因为这个只能获取公共的构造参数。
Constructor con = c.getDeclaredConstructor(String.class);//报错IllegalAccessException,非法的访问
con.setAccessible(true);//值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
Object obj = con.newInstance("张伟");
System.out.println(obj);
}
}
反射获取成员变量并使用
package cn.my.Reflect_03;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.jar.Attributes.Name;
/*
* 通过反射获取成员变量并使用
*/
public class ReflectDemo1 {
public static void main(String[] args) throws Exception {
Class c = Class.forName("cn.my.Reflect_01.Person");
//获取所有的成员变量
//Field[] fields =c.getFields();只能获取公共的成员变量
Field[] fields = c.getDeclaredFields();//获取所有的成员变量
for(Field field : fields) {
System.out.println(field);
}
/*
* Person p = new Person();
* p.address = "四川"
*/
//通过无参构造方法创建对象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
//获取单个成员变量
//获取address并对其赋值
Field addressFild = c.getField("address");
//public void set(Object obj, Object value)将指定对象变量上此 Field 对象表示的字段设置为指定的新值
addressFild.set(obj,"四川"); //给obj对象的addressField字段设置值为“四川”;
System.out.println(obj);
//获取age并对其赋值
Field nameField = c.getDeclaredField("name");
nameField.setAccessible(true);//Person的name是私有的成员变量
nameField.set(obj, "张三");
System.out.println(obj );
}
}
反射获取成员方法并使用
package cn.my.Reflect_04;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectDemo1 {
public static void main(String[] args) throws Exception {
Class c = Class.forName("cn.my.Reflect_01.Person");
//获取所有的方法
// Method[] methods = c.getMethods();//获取自己的包括父亲的方法
Method[] methods = c.getDeclaredMethods(); //获取自己的所有的方法
for(Method method : methods) {
System.out.println(method);
}
Constructor con = c.getConstructor();
Object obj = con.newInstance();
//获取单个方法并使用
/**
* 调用无参的公共类型的方法
* 调用Person中的public void show()方法
* 相当于Person p = new Person(); p.show();
*/
/*
*public Method getMethod(String name, Class<?>... parameterTypes)
*name用于指定所需方法的简称。
*parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组,如果 parameterTypes 为 null,则按空数组处理
*/
Method m1 = c.getMethod("show");
//public Object invoke(Object obj, Object... args)
//返回值是Object接收,第一个参数表示对象是谁,第二个参数表示调用该方法的实际参数
m1.invoke(obj);//调用obj对象的m1方法。
/**
* 调用带一个参的方法
* 调用public void method(String string){}方法
*/
Method m2 = c.getMethod("method", String.class);
m2.invoke(obj, "hello");
/**调用带多个参数的方法
* public String getString(String s,int i){ }
*/
Method m3 = c.getMethod("getString", String.class , int.class);
Object obgString = m3.invoke(obj, "hello" ,100);
//String s = m3.invoke(obj, "hello" ,100);//得到返回值
System.out.println(obgString);
/**
* 调用一个私有方法
* private void function() {}
*/
Method m4 = c.getDeclaredMethod("function");
m4.setAccessible(true);
m4.invoke(obj);
}
}
Person.class
package cn.my.Reflect_01;
public class Person {
private String name;
int age;
public String address;
public String getName() {
return name;
}
public Person() {
super();
}
private Person(String name) {
this.name = name;
}
Person(String name,String address) {
this.name = name;
this.address = address;
}
public Person(String name, int age, String address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
}
public void show() {
System.out.println("show");
}
private void function() {
System.out.println("function");
}
public void method(String string) {
System.out.println("method "+string);
}
public String getString(String s,int i) {
return s+" "+i;
}
}