------- android培训、java培训、期待与您交流! ----------
反射(Relfect)概述:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。
//创建一个被影射的类
package cn.itcast_01_Reflect;
/*
* 人类
*/
public class Person {
public String name;
public int age;
private String address;
//构造方法
public Person() {
super();
}
private Person(String name) {
super();
this.name = name;
}
public Person(String name, int age, String address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
//普通方法
//getXxx SetXxx
//没有返回值 没有参数的方法
public void method1(){
System.out.println("没有返回值 没有参数的方法");
}
//没有返回值, 有参数的方法
public void method2(String name){
System.out.println("没有返回值, 有参数的方法 name:" + name);
}
//有返回值,没有参数的方法
public int method3(){
System.out.println("有返回值,没有参数的方法");
return 12345;
}
//有返回值,有参数的方法
public String method4(String str){
System.out.println("有返回值,有参数的方法 , str:" + str);
return "day27" + str;
}
//私有方法
private void method5(){
System.out.println("我是私有方法, 呵呵");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", address=" + address
+ "]";
}
}
package cn.itcast_01_Reflect;
/*
Reflect 反射
获取字节码文件对象的方式:
方式1:
通过Object类中getClass()方法, 返回当前对象所对应的字节码文件对象
方式2:
通过类名.class 完成 返回一个字节码文件对象
方式3:(开发中使用)
通过Class类中的forName()方法完成
public static Class<?> forName(String className) className需要使用的是 完整的类名称 包名.类名
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
//方式1:
//Person p = new Person();
//Class c = p.getClass();
//System.out.println(c);
//方式2:
// Integer.class;
// int.class;
// String.class;
// char.class
//Class c2 = Person.class;
//System.out.println(c2);
//方式3
Class c3 = Class.forName("cn.itcast_01_Reflect.Person");
System.out.println(c3);
}
}
package cn.itcast_02_Reflect_Constructor;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import cn.itcast_01_Reflect.Person;
/*
反射: 通过构造方法 创建对象
方式1:
Person p = new Person();
syso(p)
方式2: 通过反射的方式 创建对象
获取构造方法:
获取所有的构造方法:
public Constructor<?>[] getConstructors() 获取的是所有的public修饰的构造方法
获取某一个构造方法:
public Constructor<T> getConstructor(Class<?>... parameterTypes) 获取的是指定的public修饰的构造方法
Constructor类中的方法: 创建对象
public T newInstance(Object... initargs)
参数: Object... initargs 创建对象的时候,要使用的具体参数数据。
* 案例: 通过反射机制, 使用空参数构造方法 创建对象。
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//方式1
//Person p = new Person();
//System.out.println(p);
//方式2 通过反射的方式 创建对象
//a: 获取到字节码文件对象
Class c = Class.forName("cn.itcast_01_Reflect.Person");
//b: 获取到空参数构造方法
//获取所有的构造方法:public Constructor<?>[] getConstructors()
// Constructor[] cons = c.getConstructors();
// for (Constructor con : cons) {
// System.out.println(con);
// }
//public Constructor<T> getConstructor(Class<?>... parameterTypes)
//public Person() {}
Constructor con = c.getConstructor(null);
System.out.println(con);
//c: 通过空参数构造方法, 创建对象
//public T newInstance(Object... initargs)
Object obj = con.newInstance(null);
System.out.println(obj);
}
}
package cn.itcast_02_Reflect_Constructor;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/*
案例: 通过反射机制, 使用有参数构造方法,创建对象
public Person(String name, int age, String address) {}
方式1:
Person p = new Person("小明", 20, "北京");
syso(p)
方式2:
通过反射机制
*/
public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取Person类的字节码文件对象
Class c = Class.forName("cn.itcast_01_Reflect.Person");
//获取有参数的构造方法
Constructor con = c.getConstructor(String.class, int.class, String.class);
//通过构造方法,创建对象
Object obj = con.newInstance("小明", 20, "北京");
System.out.println(obj);
}
}
package cn.itcast_02_Reflect_Constructor;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/*
通过反射机制, 使用私有的构造方法,创建对象
private Person(String name) {}
方式1: 不行
Person p = new Person("小明");
syso(p);
方式2:可以
通过反射的方式
构造方法的获取:
多个构造方法:
public Constructor<?>[] getDeclaredConstructors() : 获取所有的构造方法, 包含私有的
指定的构造方法:
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 可以获取私有的构造方法
AccessibleObject类
public void setAccessible(boolean flag) 取消java中 权限修饰符的检测
*/
public class ReflectDemo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取Person 类的字节码文件
Class c = Class.forName("cn.itcast_01_Reflect.Person");
//获取私有的构造方法
//多个构造方法:
//public Constructor<?>[] getDeclaredConstructors() : 获取所有的构造方法, 包含私有的
// Constructor[] cons = c.getDeclaredConstructors();
// for (Constructor con : cons) {
// System.out.println(con);
// }
//指定的构造方法:
//public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 可以获取私有的构造方法
Constructor con = c.getDeclaredConstructor(String.class);
//System.out.println(con);
//IllegalAccessException 非法的访问异常
//暴力 访问
//AccessibleObject
//public void setAccessible(boolean flag) 取消java中 权限修饰符的检测
con.setAccessible(true);
//创建对象
Object obj = con.newInstance("小明");
System.out.println(obj);
}
}
package cn.itcast_03_Reflect_Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/*
* 案例: 我想访问Person类中的无参数无返回值的方法
* public void method1(){
System.out.println("没有返回值 没有参数的方法");
}
方式1:
Person p = new Person();
p.method1();
方式2:
反射的方式
获取方法
多个方法
public Method[] getMethods() 获取所有的public 的方法, 包含父类中的public 方法
某一个方法
public Method getMethod(String name, Class<?>... parameterTypes)获取指定的public 的方法
执行方法,通过Method类中的方法
public Object invoke(Object obj, Object... args)
//参数:
Object obj 执行的是哪个对象中的该方法
Object... args 方法的参数具体数据
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取Person类 字节码文件对象
Class c = Class.forName("cn.itcast_01_Reflect.Person");
//获取构造方法,创建对象
Constructor con = c.getConstructor(null);
Object obj = con.newInstance(null);
//获取到你想调用的方法
//public Method[] getMethods() 获取所有的public 的方法, 包含父类中的public 方法
// Method[] methods = c.getMethods();
// for (Method method : methods) {
// System.out.println(method);
// }
//public Method getMethod(String name, Class<?>... parameterTypes)获取指定的public 的方法
//public void method1(){}
Method method = c.getMethod("method1", null);
System.out.println(method);
//调用方法,并指定调用的是哪个对象中的该方法
//public Object invoke(Object obj, Object... args)
method.invoke(obj, null);
}
}
package cn.itcast_03_Reflect_Method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/*
案例: 我想访问Person类中的无参数无返回值的方法
//有返回值,有参数的方法
public String method4(String str){}
*/
public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
//获取Person类字节码文件对象
Class c = Class.forName("cn.itcast_01_Reflect.Person");
//通过构造方法, 创建对象
Object obj = c.getConstructor(null).newInstance(null);
//获取指定的方法
Method method = c.getMethod("method4", String.class);
//执行方法
Object result = method.invoke(obj, "itcast0322");
System.out.println(result);
}
}
package cn.itcast_03_Reflect_Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/*
案例: 我想访问Person类中的私有方法
方法的获取:
多个方法:
public Method[] getDeclaredMethods() 包含私有方法的获取
注意: 该方法,只能获取到本类中的所有方法,包含私有的, 不能获取父类的方法
某一个方法:
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) 包含私有方法的获取
*/
public class ReflectDemo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取字节码文件对象
Class c = Class.forName("cn.itcast_01_Reflect.Person");
//通过构造方法,创建对象
Constructor con = c.getConstructor(null);
Object obj = con.newInstance(null);
//获取指定的私有方法
//多个方法: public Method[] getDeclaredMethods() 包含私有方法的获取
// Method[] methods = c.getDeclaredMethods();
// for (Method method : methods) {
// System.out.println(method);
// }
//某一个方法: public Method getDeclaredMethod(String name, Class<?>... parameterTypes) 包含私有方法的获取
//private void method5(){}
Method method = c.getDeclaredMethod("method5", null);
//暴力 访问
method.setAccessible(true);
//调用私有方法
method.invoke(obj, null);
}
}
package cn.itcast_04_Reflect_Field;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/*
通过反射的方式, 获取指定的成员变量(字段) public修饰的成员变量
public String name;
方式1:
person p = new Person();
syso(p);
p.name = "小明";
syso(p);
方式2:
反射的方式,来实现方式1的操作
获取成员变量
多个成员变量
public Field[] getFields() 获取到所有的public 修饰的成员变量
public Field[] getDeclaredFields() 可以获取所有的成员变量, 包含私有的
某一个成员变量
public Field getField(String name) 获取public 指定的成员变量
public Field getDeclaredField(String name) 获取指定的成员变量,包含私有的
Field类中的方法:
public void set(Object obj, Object value) 为 指定对象中当前成员变量进行赋值
public Object get(Object obj) 返回指定对象中 当前的成员变量值
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
// 获取Person字节码文件
Class c = Class.forName("cn.itcast_01_Reflect.Person");
// 通过构造方法,创建对象
Constructor con = c.getConstructor(null);
Object obj = con.newInstance(null);
// 获取指定的成员变量 name
//多个成员变量 public Field[] getFields()
// Field[] fields = c.getFields();
// for (Field field : fields) {
// System.out.println(field);
// }
//某一个成员变量 public Field getField(String name)
//public String name;
Field fieldName = c.getField("name");
Field fieldAge = c.getField("age");
//System.out.println(fieldName);
//获取私有的成员变量
//private String address
Field fieldAddress = c.getDeclaredField("address");
System.out.println(obj);
// 使用成员变量
fieldName.set(obj, "小明");
fieldAge.set(obj, 20);
//使用私有的成员变量
fieldAddress.setAccessible(true);//开启暴力访问
fieldAddress.set(obj, "上海");
System.out.println(obj);
}
}
package cn.itcasty_05_Reflect_Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
/*
反射 在现实开发中的使用
泛型的擦除技术:
泛型的约束它只能够在编译器有效,当编译通过后,产生了一个.class字节码文件,
该字节码文件中,没有泛型
注意: 那么,当我们使用反射技术的时候,所有的类中都是没有泛型约束的
*/
public class ReflectTest {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
ArrayList<Integer> list =new ArrayList<Integer>();
list.add(20);
list.add(30);
list.add(40);
//由于集合中的泛型为Integer类型,所以我们不能存储其他类型
//list.add("哈哈");
//获取字节码文件对象
//Class c = Class.forName("java.util.ArrayList");
Class c = ArrayList.class;
//通过构造方法,创建对象
//list 对象有了, 不需要创建
//获取指定的方法
//public boolean add(E e)
Method methodAdd = c.getMethod("add", Object.class);
//执行方法
methodAdd.invoke(list, "哈哈");
System.out.println(list);
}
}