反射
1.获取Class对象的方法
public class Test {
public static void main(String[] args) {
//通过类获取Class对象
Class clazz1 = Student.class;
//通过对象获取Class对象
Student s = new Student(18, 0);
Class clazz2 = s.getClass();
//通过forName静态方法
try {
Class clazz3 = Class.forName("cn.it.ref.Student");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.获取构造器
方法 |
描述 |
Connstructor getConstructor(Class>...paramterTypes) |
获取Class对象对应类的带指定参数列表的public构造器 |
Connstructor> getContructors() |
获取Class对象对应类的所有public构造器 |
Connstructor getDeclaredConstructor (Class>...paramterTypes) |
获取Class对象对应类的带指定参数列表的构造器,与访问修饰符无关 |
Connstructor> getDeclaredConstructors() |
获取Class对象对应类的所有构造器,与访问修饰符无关 |
2.1示例
public class Test2 {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
Class clazz = Student.class;
//获取public修饰的构造方法
Constructor[] c1 = clazz.getConstructors();
// for (Constructor constructor : c1) {
// System.out.println(constructor);
// }
//获取所有构造方法,与访问修饰符无关
Constructor[] c2 = clazz.getDeclaredConstructors();
// for (Constructor constructor : c2) {
// System.out.println(constructor);
// }
//获取指定的public修饰的构造方法
Constructor c = clazz.getConstructor(int.class,double.class);
System.out.println(c);
// Constructor tempc = clazz.getConstructor(double.class);
//获取指定参数的构造器,与访问修饰符无关
Constructor construct1 = clazz.getDeclaredConstructor(double.class);
System.out.println(construct1);
Constructor construct2 = clazz.getDeclaredConstructor();
System.out.println(construct2);
}
}
3.获取成员方法
方法 |
描述 |
Method getMethod(String name,Class>...paramterTypes) |
获取指定名称和参数类型class对象的public修饰方法 |
Method[] getMethods() |
获取所有public修饰的成员方法以及继承的方法,包括静态方法 |
Method getDeclaredMethod(String name,Class>...paramterTypes) |
获取指定名称和参数类型class对象的方法,与访问修饰符无关 |
Method[] getDeclaredMethods() |
获取自身声明的所有成员方法,与访问修饰符无关 |
3.1示例
public class MethodTest {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取Class对象
Student s = new Student(0);
Class clazz = s.getClass();
//获取public修饰的方法包含父类public修饰的方法
Method[] methods = clazz.getMethods();
// for (Method method : methods) {
// System.out.println(method);
// }
//获取自身声明的所有方法,与访问修饰符无关
Method[] methods2 = clazz.getDeclaredMethods();
// for (Method method : methods2) {
// System.out.println(method);
// }
//获取指定参数的public修饰的成员方法
// Method method = clazz.getMethod("newObject");
// System.out.println(method);
//获取指定参数的自身声明的方法,与访问修饰符无关
Method method2 = clazz.getDeclaredMethod("newObject", int.class);
// System.out.println(method2);
// method2.setAccessible(true);
// method2.invoke(s,2);
Method method3 = clazz.getDeclaredMethod("makeMoney");
method3.invoke(s);
Method method4 = clazz.getDeclaredMethod("sleep",String.class);
method4.invoke(null,"蔡老师");
}
}
4.获取成员变量
方法 |
描述 |
Field getField(String name) |
获取指定名称的public修饰的成员变量 |
Field[] getFields() |
获取所有的public修饰的成员变量,包括从父类继承的成员变量 |
Field getDeclaredField(String name) |
获取指定名称的成员变量,与访问权限无关 |
Field[] getDeclaredFields() |
获取所有的成员变量,与访问修饰符无关 |
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Son s = new Son();
Class clazz = s.getClass();
//获取自身和父类public修饰的成员变量
Field[] fields = clazz.getFields();
// for (Field field : fields) {
// System.out.println(field);
// }
//获取自身声明的成员变量,与访问修饰符无关
Field[] fields2 = clazz.getDeclaredFields();
// for (Field field : fields2) {
// System.out.println(field);
// }
//根据指定名称获取自身和父类public修饰的成员变量属性
Field f1 = clazz.getField("age");
f1.setInt(s, 10);
System.out.println(s.age);
Field f3 = clazz.getField("name");
f3.set(s, "张三");
System.out.println(s.name);
//根据指定名称获取属性,与访问修饰符无关
Field f2 = clazz.getDeclaredField("width");
System.out.println(f2);
f2.setAccessible(true);
f2.setInt(s, 100);
System.out.println(s.getWidth());
}
5.获取注解
6.Method对象方法
方法 |
描述 |
invoke(Object obj,Object...obj) |
调用对象方法 |
setAccessible(boolean flag) |
设置私有方法可访问 |
7.实例化对象
方法 |
描述 |
clazz.newInstance() |
只能调用默认无参构造方法 |
Constructor.newInstance(Object..obj) |
调用对应的构造方法 |
7.1示例
public class NewInstance {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class clazz = Class.forName("cn.itlaobing.ref2.Student");
Constructor c = clazz.getDeclaredConstructor(int.class);
c.setAccessible(true);
//利用构造方法newInstanc方法
Student s = (Student)c.newInstance(18);
System.out.println(s.getAge());
//利用class对象newInstance,调用默认无参构造
// Student s2 = (Student) clazz.newInstance();
// System.out.println(s2.getAge());
}
}
8.作业实例
1.使用反射创建FileInputStream以及BufferedInputStream读取某个文件,并利用反射创建
FileOutputStream和BufferedOutputStream对象,将文件写入到E://File(如果使用File对象)
也必须使用反射创建对象
package com.itlaobing.z0830;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@SuppressWarnings("all")
public class ReflectFileTest {
public static void main(String[] args) {
// 获取FileInputStream类信息
Class clazz1 = FileInputStream.class;
// 获取BufferedInputStream类信息
Class clazz2 = BufferedInputStream.class;
// 获取FileOutputStream类信息
Class clazz3 = FileOutputStream.class;
// 获取BufferedOutputStream类信息
Class clazz4 = BufferedOutputStream.class;
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Method bisClose = null;
Method bosClose = null;
try {
// 获取FileInputStream类构造方法
Constructor constructor = clazz1.getDeclaredConstructor(String.class);
// 通过构造器.newInstance创建对象
fis = (FileInputStream) constructor.newInstance("D:/1/Menu.java");
// 获取BufferedInputStream类构造方法
Constructor constructor2 = clazz2.getDeclaredConstructor(InputStream.class);
// 通过构造器.newInstance创建对象
bis = (BufferedInputStream) constructor2.newInstance(fis);
// 获取BufferedInputStream的read()方法
// Method read = clazz2.getMethod("read");
// 获取BufferedInputStream的read(byte[] b)方法(调用的FileinputStream的read(byte[] b))
Method read = clazz2.getMethod("read", byte[].class);
// 获取BufferedInputStream的close()方法
bisClose = clazz2.getDeclaredMethod("close");
// 获取FileOutputStream类构造方法
Constructor constructor3 = clazz3.getDeclaredConstructor(String.class);
// 通过构造器.newInstance创建对象
fos = (FileOutputStream) constructor3.newInstance("D:/1/File/Menu.java");
// 获取BufferedOutputStream类构造方法
Constructor constructor4 = clazz4.getDeclaredConstructor(OutputStream.class);
// 通过构造器.newInstance创建对象
bos = (BufferedOutputStream) constructor4.newInstance(fos);
// 获取BufferedOutputStream的write()方法
// Method write = clazz4.getMethod("write", int.class);
// 获取BufferedOutputStream的write(byte[] b)方法(调用的FileOutputStream的write(byte[] b))
Method write = clazz4.getMethod("write", byte[].class);
// 获取BufferedOutputStream的close()方法(其实获得的是父类FilterOutputStream的close()方法)
bosClose = clazz4.getMethod("close");
// 读写文件
int i = 0;
// 利用read.invoke获得read()方法,利用write.invoke获得write(int i)方法
// while ((i = (int) read.invoke(bis)) > -1) {
// write.invoke(bos, i);
// }
byte[] b = new byte[1024];
// 利用read.invoke获得read(byte[] b )方法,利用write.invoke获得write(byte[] b)方法
while ((i = (int) read.invoke(bis, b)) > -1) {
write.invoke(bos, b);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally {
try {
bisClose.invoke(bis);
bosClose.invoke(bos);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}