反射概述
Java反射机制:是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展。
获取Class类的对象
我们要想通过反射去使用一个类,首先我们要获取到该类的字节码文件对象,也就是类型为Class类型的对象
以下三种方式可以获取Class类型的对象
1.使用类的class属性来获取该类对应的Class对象。举例: Student.class将会返回Student类对应的Class对象
2.调用对象的getClass()方法,返回该对象所属类对应的Class对象
该方法是Object类中的方法,所有的Java对象都可以调用该方法
3.使用Class类中的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,也就是完整包名的路径
package fanshe;
/*
* 以下三种方式可以获取Class类型的对象
1.使用类的class属性来获取该类对应的Class对象。举例: Student.class将会返回Student类对应的Class对象
2.调用对象的getClass()方法,返回该对象所属类对应的Class对象
该方法是Object类中的方法,所有的Java对象都可以调用该方法
3.使用Class类中的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,也就是完整包名的路径
*/
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException {
//使用类的class属性来获取该类对应的Class对象
Class<Student> c1=Student.class;
System.out.println(c1); //class fanshe.Student
Class<Student> c2=Student.class;
System.out.println(c1==c2); //true
//调用对象的getClass()方法,返回该对象所属类对应的Class对象
Student s=new Student();
Class<? extends Student> c3=s.getClass();
System.out.println(c1==c3); //true
//使用Class类中的静态方法forName(String className)
Class<?> c4=Class.forName("fanshe.Student");
System.out.println(c1==c4); //true
}
}
反射获取构造方法并使用
Class类中用于获取构造方法的方法:
Constructor<?>[]getConstructors():返回所有公共构造方法对象的数组
Constructor<?>l[getDeclaredConstructors():返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):返回单个构造方法对象
Constructor类中用于创建对象的方法:
T newInstance(Object... initargs):根据指定的构造方法创建对象
package fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/*
* Class类中用于获取构造方法的方法:
Constructor<?>[]getConstructors():返回所有公共构造方法对象的数组
Constructor<?>l[getDeclaredConstructors():返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):返回单个构造方法对象
Constructor类中用于创建对象的方法:
T newInstance(Object...initargs):根据指定的构造方法创建对象
*/
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
//获取Class对象
Class<?> c=Class.forName("fanshe.Student");
//Constructor<?>[]getConstructors():返回所有公共构造方法对象的数组
Constructor<?>[] cons=c.getConstructors();
for(Constructor cons1:cons) {
System.out.println(cons1);
}
System.out.println("------------------");
//Constructor<?>[]getDeclaredConstructors():返回所有构造方法对象的数组
Constructor<?>[] dcons=c.getDeclaredConstructors();
for(Constructor dcons1:dcons) {
System.out.println(dcons1);
}
System.out.println("------------------");
//Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
//参数:你要获取的构造方法的参数的个数和数据类型对应的字节码文件对象
Constructor<?> con=c.getConstructor();
//T newInstance(Object...initargs):根据指定的构造方法创建对象
Object obj=con.newInstance();
System.out.println(obj);
}
}
Student类:
package fanshe;
public class Student {
private String name;
int age;
public String address;
public Student () {}
private Student (String name) {
this.name=name;
}
Student (String name,int age){
this.name=name;
this.age=age;
}
public Student (String name,int age,String address) {
this.name=name;
this.age=age;
this.address=address;
}
private void function() {
System.out.println( "function" );
}
public void method1() {
System.out.println( "method" );
}
public void method2(String s) {
System.out.println( "method : " + s);
}
public String method3(String s, int i) {
return s + "," +i;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
练习1:通过反射实现如下操作
Student s = new Student("林青霞",30,"西安");
System.out.printIn(s);
package fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Demo4 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalArgumentException, InvocationTargetException, IllegalAccessException {
//获取Class对象
Class<?> c=Class.forName("fanshe.Student");
//Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
Constructor<?> con=c.getConstructor(String.class,int.class,String.class);//基本数据类型也可以通过.Class得到对应的Class类型
//T newInstance(Object...initargs):根据指定的构造方法创建对象
Object obj= con.newInstance("林青霞",30,"福州");
System.out.println(obj);
}
}
练习2:通过反射实现如下操作
Student s = new Student("林青霞");
System.out.printIn(s);
public void setAccessible(boolean flag):值为true,取消访问检查
package fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Demo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取Class对象
Class<?> c=Class.forName("fanshe.Student");
//Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):返回单个构造方法对象
Constructor<?> con=c.getDeclaredConstructor(String.class);
//暴力反射
//public void setAccessible (boolean flag):值为true,取消访问检查
con.setAccessible(true);
Object obj=con.newInstance("林青霞");
System.out.println(obj);
}
}
反射获取成员变量并使用
Class类中用于获取成员变量的方法
Field[] getFields():返回所有公共成员变量对象的数组
Field[] getDeclaredFields():返回所有成员变量对象的数组
Field getField(String name):返回单个公共成员变量对象
Field getDeclaredField(String name):返回单个成员变量对象
Field类中用于给成员变量赋值的方法
void set(Object obj, Object value):给obj对象的成员变量赋值为value
package fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/*
* Field[] getFields():返回所有公共成员变量对象的数组
Field[] getDeclaredFields():返回所有成员变量对象的数组
Field getField(String name):返回单个公共成员变量对象
Field getDeclaredField(String name):返回单个成员变量对象
Field类中用于给成员变量赋值的方法
void set(Object obj, Object value):给obj对象的成员变量赋值为value
*/
public class Demo5 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取Class对象
Class<?> c=Class.forName("fanshe.Student");
//Field[] getFields():返回所有公共成员变量对象的数组
Field[] gfs=c.getFields();
for(Field gfs1:gfs) {
System.out.println(gfs1);
}
System.out.println("-----------------");
//Field[] getDeclaredFields():返回所有成员变量对象的数组
Field[] gdfs=c.getDeclaredFields();
for(Field gdfs1:gdfs) {
System.out.println(gdfs1);
}
System.out.println("-----------------");
//Field getField(String name):返回单个公共成员变量对象
Field gfd=c.getField("address");
//获取无参构造方法创建对象
//Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
Constructor<?> con=c.getConstructor();
Object obj=con.newInstance();
//Field类中用于给成员变量赋值的方法
//void set(Object obj, Object value):给obj对象的成员变量赋值为value
gfd.set(obj, "福州");//给obj的成员变量gfd赋值为福州
System.out.println(obj);
}
}
Student类:
package fanshe;
public class Student {
private String name;
int age;
public String address;
public Student () {}
private Student (String name) {
this.name=name;
}
Student (String name,int age){
this.name=name;
this.age=age;
}
public Student (String name,int age,String address) {
this.name=name;
this.age=age;
this.address=address;
}
private void function() {
System.out.println( "function" );
}
public void method1() {
System.out.println( "method" );
}
public void method2(String s) {
System.out.println( "method : " + s);
}
public String method3(String s, int i) {
return s + "," +i;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
练习:通过反射实现如下操作
Student s = new Student(;s.name = "林青霞");
s.age = 30;
s.address ="福州"; System.out.println(s);
package fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class Demo6 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取Class对象
Class<?> c=Class.forName("fanshe.Student");
//获取无参构造方法创建对象
//Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
Constructor con=c.getConstructor();
Object obj=con.newInstance();
//------------name
//Field getDeclaredField(String name):返回单个成员变量对象
Field fname=c.getDeclaredField("name");
//暴力反射
//public void setAccessible (boolean flag):值为true,取消访问检查
fname.setAccessible(true);
fname.set(obj, "林青霞");
//------------age
Field fage=c.getDeclaredField("age");
fage.setAccessible(true);
fage.set(obj, 30);
//------------address
Field fadd=c.getDeclaredField("address");
fadd.setAccessible(true);
fadd.set(obj, "福州");
//------------输出
System.out.println(obj);
}
}
Student类:
package fanshe;
public class Student {
private String name;
int age;
public String address;
public Student () {}
private Student (String name) {
this.name=name;
}
Student (String name,int age){
this.name=name;
this.age=age;
}
public Student (String name,int age,String address) {
this.name=name;
this.age=age;
this.address=address;
}
private void function() {
System.out.println( "function" );
}
public void method1() {
System.out.println( "method" );
}
public void method2(String s) {
System.out.println( "method : " + s);
}
public String method3(String s, int i) {
return s + "," +i;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
反射获取成员方法并使用
Class类中用于获取成员方法的方法:
Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?> ... parameterTypes)∶返回单个公共成员方法对象Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象
Method类中用于调用成员方法的方法
Object invoke(Object obj, Object..args):调用obj对象的成员方法,参数是args,返回值是Object类型
package fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/*
* Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?> ... parameterTypes)∶返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象
Method类中用于调用成员方法的方法
Object invoke(Object obj, Object..args):调用obj对象的成员方法,参数是args,返回值是Object类型
*/
public class Demo7 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取Class对象
Class<?> c=Class.forName("fanshe.Student");
//Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
Method[] m1=c.getMethods();
for(Method m11:m1) {
System.out.println(m11);
}
System.out.println("------------");
//Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
Method[] md1=c.getDeclaredMethods();
for(Method md11:md1) {
System.out.println(md11);
}
System.out.println("------------");
//Method getMethod(String name, Class<?> ... parameterTypes)∶返回单个公共成员方法对象
Method m=c.getMethod("method1");
//获取无参构造方法创建对象
//Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
Constructor<?> con=c.getConstructor();
Object obj=con.newInstance();
//Method类中用于调用成员方法的方法
//Object invoke(Object obj, Object..args):调用obj对象的成员方法,参数是args,返回值是Object类型
m.invoke(obj);
}
}
Student类:
package fanshe;
public class Student {
private String name;
int age;
public String address;
public Student () {}
private Student (String name) {
this.name=name;
}
Student (String name,int age){
this.name=name;
this.age=age;
}
public Student (String name,int age,String address) {
this.name=name;
this.age=age;
this.address=address;
}
private void function() {
System.out.println( "function" );
}
public void method1() {
System.out.println( "method" );
}
public void method2(String s) {
System.out.println( "method : " + s);
}
public String method3(String s, int i) {
return s + "," +i;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
练习:通过反射实现如下操作·
student s = new Student();
s.method1();
s.method2("林青霞");
String ss = s.method3("林青霞",30); System.out.printIn(ss);
s.function();
package fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo8 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取Class对象
Class<?> c=Class.forName("fanshe.Student");
//获取无参构造方法创建对象
Constructor<?> con=c.getConstructor();
Object obj=con.newInstance();
//--------------------s.method1();
//Method getMethod(String name, Class<?> ... parameterTypes)∶返回单个公共成员方法对象
Method m1=c.getMethod("method1");
//Method类中用于调用成员方法的方法
//Object invoke(Object obj, Object..args):调用obj对象的成员方法,参数是args,返回值是Object类型
m1.invoke(obj);
//-------------------s.method2("林青霞");
//Method getMethod(String name, Class<?> ... parameterTypes)∶返回单个公共成员方法对象
Method m2=c.getMethod("method2", String.class);
m2.invoke(obj, "林青霞");
//-------------------String ss = s.method3("林青霞",30); System.out.printIn(ss);
Method m3=c.getMethod("method3",String.class,int.class);
Object o=m3.invoke(obj, "林青霞",30);
System.out.println(o);
//------------------s.function();
Method f=c.getDeclaredMethod("function");
f.setAccessible(true);
f.invoke(obj);
}
}
Student类:
package fanshe;
public class Student {
private String name;
int age;
public String address;
public Student () {}
private Student (String name) {
this.name=name;
}
Student (String name,int age){
this.name=name;
this.age=age;
}
public Student (String name,int age,String address) {
this.name=name;
this.age=age;
this.address=address;
}
private void function() {
System.out.println( "function" );
}
public void method1() {
System.out.println( "method" );
}
public void method2(String s) {
System.out.println( "method : " + s);
}
public String method3(String s, int i) {
return s + "," +i;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
反射练习之越过泛型检查
有一个ArrayList<Integer>集合,现要在这个集合中添加一个字符串数据,如何实现?
package fanshe;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class Demo9 {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
ArrayList<Integer> array=new ArrayList<Integer>();
Class<? extends ArrayList> c=array.getClass();
Method m=c.getMethod("add",Object.class);
m.invoke(array,"hello");
m.invoke(array, "world");
System.out.println(array);
}
}
反射练习之运行配置文件指定内容
package fanshe;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class Demo10 {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
/*
* Class.txt
* className:xxxx
methodName:xxxx
*/
//加载数据
Properties pro=new Properties();
FileReader fr=new FileReader("C:\\DW\\Class.txt");
pro.load(fr);
fr.close();
/*
* className:fanshe.S
methodName:study
*/
String className=pro.getProperty("className"); //拿到fanshe.S
String methodName=pro.getProperty("methodName"); //拿到study
//通过反射来使用
Class<?> c=Class.forName(className);
Constructor<?> con=c.getConstructor();
Object obj=con.newInstance();
Method m=c.getMethod(methodName);
m.invoke(obj);
}
}
S类:
package fanshe;
public class S {
public void study() {
System.out.println("好好学习,天天向上");
}
}
T类:
package fanshe;
public class T {
public void teach() {
System.out.println("老师");
}
}
Class.txt: