反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
类初始化时机
1. 创建类的实例
2. 访问类的静态变量,或者为静态变量赋值
3. 调用类的静态方法
4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
5. 初始化某个类的子类
6. 直接使用java.exe命令来运行某个主类
类加载器
1.负责将.class文件加载到内在中,并为之生成对应的Class对象
2. 虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。
3. Bootstrap ClassLoader 根类加载器
4. Extension ClassLoader 扩展类加载器
5. Sysetm ClassLoader 系统类加载器
实例
package com.the151suggestions.reflect;
/**
* Created by wanggs on 2017/7/23.
* 所有类的对象其实都是Class的实例。
* 1. 反射就是通过Class文件对象,去使用文件中的成员变量,构造方法,成员方法
* 2. 首先得到Class文件对象,其实就是得到Class类的对象
* Class:
* 成员变量: Field
* 构造方法: Construction
* 成员方法: Method
* 获取class对象的方式
* A:Object类的getClass()
* B:数据类型的静态属性
* C: Class类中的静态方法
* Public static Class forNmae(String className)// 类的全路径
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 获取Class文件对象
// 方式 1
Person person = new Person();
Class c = person.getClass();
// 方式 2
Class c1 = Person.class;
// 方式 3
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
System.out.println(c1 == c2); // true
System.out.println(c2); // 输出 class com.the151suggestions.reflect.Person
}
}
class Person {
private String name;
public int age;
public String address;
public Person() {
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
// 方法
public void show() {
System.out.println("Person.show");
}
public void method(String s) {
System.out.println("s = " + s);
}
public String getString(String s, int i) {
return "s = " + s + "i = " + i;
}
private void function() {
System.out.println("Person.function");
}
}
通过反射获取构造方法并使用
-
获取构造方法
getConstructors
getDeclaredConstructors
实例
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 获取Class文件对象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
// 获取构造方法
Constructor[] classes = c2.getConstructors(); // 私有拿不到
for (Constructor constructor : classes){
System.out.println(constructor);
}
}
}
/**
* public com.the151suggestions.reflect.Person(java.lang.String,int,java.lang.String)
public com.the151suggestions.reflect.Person(int)
public com.the151suggestions.reflect.Person(java.lang.String)
public com.the151suggestions.reflect.Person()
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 获取Class文件对象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
// 获取构造方法
Constructor[] classes = c2.getDeclaredConstructors(); // 获取所有
for (Constructor constructor : classes){
System.out.println(constructor);
}
}
}
-
创建对象
newInstance()
con.newInstance(“zhangsan", 20);
实例
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 获取Class文件对象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
// 获取单个 public Constructor<T> getConstructor(Class<T>... args)
Constructor constructor = c2.getConstructor(String.class); // 构造方法对象
// Person p = new Person("tom);
// public T newInstance(object... arg) 获取构造方法
Person person = (Person) constructor.newInstance("tom");
System.out.println(person );
}
}
私有构造暴力访问
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 获取Class文件对象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
// 获取单个 public Constructor<T> getConstructor(Class<T>... args)
Constructor constructor = c2.getDeclaredConstructor(String.class); // 私有构造方法对象
// 暴力访问
constructor.setAccessible(true); // 取消java语言检查
Person person = (Person) constructor.newInstance("tom");
System.out.println(person );
person.show();
}
}
通过反射获取成员变量并使用
-
获取所有成员
getFields,getDeclaredFields
-
获取单个成员
getField,getDeclaredField
- 修改成员的值
set(Object obj,Object value) //将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
实例
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
// 获取Class文件对象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
// 获取所有成员变量
Field[] fields = c2.getDeclaredFields();// 包含私有
for (Field field : fields) {
System.out.println(field);
/**
* public int com.the151suggestions.reflect.Person.age
public java.lang.String com.the151suggestions.reflect.Person.address
*/
}
Constructor constructor = c2.getConstructor();
Object object = constructor.newInstance();
// 获取单个
Field field = c2.getField("address");
// 设置值 public void set(Object obj, Object value)
field.set(object,"郑州");
// Person p = new Person("郑州");
System.out.println(object);
}
}
通过反射获取成员方法并使用
-
获取所有方法
getMethods
getDeclaredMethods
实例
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
// 获取Class文件对象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
Method[] methods = c2.getMethods(); // 包括父亲的公共方法
for(Method method : methods){
System.out.println(method);
}
}
}
-
获取单个方法
getMethod
getDeclaredMethod
实例
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
// 获取Class文件对象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
Constructor constructor = c2.getConstructor();
Object object = c2.newInstance();
/**
* Person p = new Person();
* p.show();
*/
// 获取单个 public Method getMethod(String name,Class<?> args);
Method method = c2.getMethod("show");
// 调用方法 public Object invoke(Object object,Object...args );
method.invoke(object); // 调用object对的show方法
}
}
方法多个参数
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
// 获取Class文件对象
Class c2 = Class.forName("com.the151suggestions.reflect.Person");
Constructor constructor = c2.getConstructor();
Object object = c2.newInstance();
/**
* Person p = new Person();
* p.show();
*/
// 获取单个 public Method getMethod(String name,Class<?> args);
Method method = c2.getMethod("show");
// 调用方法 public Object invoke(Object object,Object...args );
method.invoke(object);
Method method1 = c2.getMethod("method", String.class);
method1.invoke(object,"tom");
Method method2 = c2.getMethod("getString",String.class,int.class);
String s = (String) method2.invoke(object,"jack",12);
System.out.println(s);
}
}
-
暴力访问
method.setAccessible(true);
案例
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
// 加载数据
Properties properties = new Properties();
FileReader reader = new FileReader("1.txt");
properties.load(reader);
reader.close();
// 获取数据
String className = properties.getProperty("className");
String methodName = properties.getProperty("methodName");
// 反射
Class c = Class.forName(className);
// 无参构造
Constructor constructor = c.getConstructor();
// 创建对象
Object object = c.newInstance();
// 调用方法
Method method = c.getMethod(methodName);
method.invoke(object);
}
}
案例操作集合
/**
* Created by wanggs on 2017/7/23.
*/
public class ArrayListDemo {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
/**
* ArrayList<Integer> 中添加字符串
*/
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(12);
Class c = arrayList.getClass();
Method method = c.getMethod("add", Object.class);
method.invoke(arrayList, "tom");
System.out.println(arrayList);
}
}
案例
package com.the151suggestions.reflect01;
import java.lang.reflect.Field;
/**
* Created by wanggs on 2017/7/23.
* public void setProperty(Object obj, String propertyName, Object value){}
* 此方法可将obj对象中名为propertyName的属性的值
*/
public class Tool {
public void setProperty(Object object, String propertyName, Object value) throws NoSuchFieldException, IllegalAccessException {
Class c = object.getClass();
// 获取成员变量
Field field = c.getDeclaredField(propertyName);
// 防止私有方法暴力访问
field.setAccessible(true);
field.set(object,value);
}
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Dog dog = new Dog();
Tool tool = new Tool();
tool.setProperty(dog,"name","花花");
System.out.println(dog);
}
}
class Dog{
String name;
public Dog() {
}
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
'}';
}
}
动态代理
package com.the151suggestions.reflect01;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* Created by wanggs on 2017/7/23.
*/
public class MyinvocationHandler implements InvocationHandler {
private Object target; // 目标对象
public MyinvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Object proxy: 被代理对象 Method method: 要调用的方法 Object[] args: 方法调用说填入的参数
System.out.println("权限认证");
Object o = method.invoke(target, args); // 调用方法传入真实主题和参数
System.out.println("日志记录");
return o; // 代理对象
}
}
package com.the151suggestions.reflect01;
import java.lang.reflect.Proxy;
/**
* Created by wanggs on 2017/7/23.
*/
public class UserDaoTest {
public static void main(String[] args) {
StudentDao studentDao = new StudentDaoImpl();
MyinvocationHandler myinvocationHandler = new MyinvocationHandler(studentDao);
StudentDao studentDao1 = (StudentDao) Proxy.newProxyInstance(studentDao.getClass().getClassLoader(),studentDao.getClass().getInterfaces(),myinvocationHandler);
studentDao1.login();
}
}
package com.the151suggestions.reflect01;
/**
* Created by wanggs on 2017/7/23.
*/
public interface UserDao {
public abstract void add();
public abstract void edit();
public abstract void delete();
}
package com.the151suggestions.reflect01;
/**
* Created by wanggs on 2017/7/23.
*/
public class UserDaoImpl implements UserDao {
@Override
public void add() {
System.out.println("权限校验");
System.out.println("UserDaoImpl.add");
System.out.println("日志记录");
}
@Override
public void edit() {
System.out.println("UserDaoImpl.edit");
}
@Override
public void delete() {
System.out.println("UserDaoImpl.delete");
}
}
1.接口定义一个人类的统称
/**
* Created by wanggs on 2017/7/14.
*/
public interface Human {
public abstract void laugh();
public abstract void cry();
public abstract void talk();
}
2.然后定义具体的人种:
package com.wanggs.factory;
/**
* Created by wanggs on 2017/7/14.
*/
public class WhiteHuman implements Human {
@Override
public void laugh() {
System.out.println("WhiteHuman.laugh");
}
@Override
public void cry() {
System.out.println("WhiteHuman.cry");
}
@Override
public void talk() {
System.out.println("WhiteHuman.talk");
}
}
package com.wanggs.factory;
/**
* Created by wanggs on 2017/7/14.
*/
public class YellowHuman implements Human {
@Override
public void laugh() {
System.out.println("YellowHuman.laugh");
}
@Override
public void cry() {
System.out.println("YellowHuman.cry");
}
@Override
public void talk() {
System.out.println("YellowHuman.talk");
}
}
3.人的工厂
package com.wanggs.factory;
/**
* Created by wanggs on 2017/7/14.
*/
public class HumanFactory {
// 第一版
/* public static Human produceHuman(String type) {
if ("yellow".equals(type)) {
return new YellowHuman();
} else if ("white".equals(type)) {
return new WhiteHuman();
} else if ("black".equals(type)) {
return new BlackHuman();
}
System.out.println("有误");
return null;
}*/
//第二版
/* public static Human produceYellow() {
return new YellowHuman();
}
public static Human produceBlack() {
return new BlackHuman();
}*/
//第三版 使用反射
public static Human createHuman(Class c) {
Human human = null;
try {
human = (Human) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
System.out.println("颜色");
} catch (IllegalAccessException e) {
System.out.println("人定义错误");
} catch (ClassNotFoundException e) {
System.out.println("null");
}
return human;
}
}
4. 测试
package com.wanggs.factory;
/**
* Created by wanggs on 2017/7/14.
*/
public class NvWa {
public static void main(String[] args) {
Human human = HumanFactory.createHuman(YellowHuman.class);
human.laugh();
}
}