Java反射:一个类的组成部分( Field,Method,Constructor等 )。
反射就是程序运行的时候加载类,并解剖出各个类的组成部分。
Such as( 自己总结 ): 比如说有个Person类(人类)。然后对这个人进行开刀(然后看到他的心,有心才有一切(构造函数)、
肝(属性)、脾(属性)、肺(属性)、肾(属性)等)。 再比如说人的肝可以喝酒( Java方法 drinkWine() )...然后就知道了这个人内部的一切。
使用Java反射类来干什么? 首先先了解构造函数,属性,方法是实现什么功能?有什么特性?
1. 构造函数:创建对象
2. 属性:封装数据
3. 方法:调用执行(某个功能)
框架的简单理解也好像如此。当你写好Java类属性,构造函数,方法,和配置文件的时候,程序启动的时候,框架就在配置文件或扫描注解获得你已经写好的类,并进行解剖类的各个部门,帮你实例化对象,帮你设置属性,帮你调用方法。说着容易,但是如果上手自己去写,是需要很强的的扎实的Java技能。
一、Java反射获取Class的三种方式和通过Class对象获取构造器(Constructor)对象来进行new对象。
package com.java.a.iReflection;
import java.util.List;
public class Person {
public String myPublic = "public";
private String name = "zhangsan";
private int age;
private List<?> list = new ArrayList<>();
public Person() {}
public Person(String name) {
this.name = name;
}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
@SuppressWarnings("all")
private Person(List<?> list) {
this.list = list;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", list=" + list + "]";
}
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 List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
/*反射5个方法和一个main方法*/
public void show(){
System.out.println("反射无参构造方法!");
}
public void show(String name,int luckyNum){
System.out.println(name + "的幸运数字是:" + luckyNum);
}
public Class<?>[] show(String name,int[] luckyNum){
System.out.println(name + "的幸运数字是:" + luckyNum);
return new Class[]{String.class};
}
@SuppressWarnings("unused")
private void show(InputStream in){
System.out.println(in);
}
public static void show(int num){
System.out.println(num);
}
public static void main(String[] args) {
System.out.println("main方法");
}
}
package com.java.a.iReflection;
import java.lang.reflect.Constructor;
import org.junit.Test;
import com.java.a.Person;
/**
* Java反射:一个类的组成部分( Field,Method,Constructor等 )。
* 反射就是加载类,并解剖出各个类的组成部分。
* Such as(自己总结):比如说有个Person类(人类)。然后对这个人进行开刀(然后看到他的心,有心才有一切(构造函数)、
* 肝(属性)、脾(属性)、肺(属性)、肾(属性)等)。
* 再比如说人的肝可以喝酒( Java方法 drinkWine() )...然后就知道了这个人内部的一切。
*
* 使用Java反射类来干什么?
* 首先先了解构造函数,属性,方法是实现什么功能?有什么特性?
* 1. 构造函数:创建对象
* 2. 属性:封装数据
* 3. 方法:调用执行(某个功能)
* @author TS
*
*/
public class IReflect {
public static void main(String[] args) throws Exception {
//无参
Person person1 = reflectConstructorForInstance(Person.class);
Person person2 = (Person) reflectConstructorForInstance("com.java.a.Person");
System.out.println(person1);
System.out.println(person2);
//一个String参数
Person person3 = reflectConstructorForInstance1(Person.class);
System.out.println(person3);
Person person4 = (Person) reflectConstructorForInstance1("com.java.a.Person","java.lang.String");
System.out.println(person4);
//一个list参数
Person person5 = reflectConstructorForInstance2(Person.class);
System.out.println(person5);
}
/**
* 反射第一步:加载类( 三种方式 )
*
* @throws ClassNotFoundException
*
*/
@Test
public void loadClass() throws ClassNotFoundException{
//1.
Class<?> clazz = Class.forName("com.java.a.Person");
System.out.println(clazz); //==>class com.java.a.Person
//2.
Class<?> clazz1 = Person.class;
System.out.println(clazz1); //==>class com.java.a.Person
//3.
Class<?> clazz2 = new Person().getClass();
System.out.println(clazz2); //==>class com.java.a.Person
}
/**
* 解剖类的构造函数,获取无参构造函数实例
* public Person() {}
* @param <T>:传入的类型
* @param clazz:加载Class对象
* @return T (Object)
*/
public static <T> T reflectConstructorForInstance(Class<T> clazz) throws Exception{
Constructor<T> constructor = clazz.getConstructor(); //获取无参构造方法对象
return constructor.newInstance(); //创建对象
}
/**
*
* @param qualifiedName
* @return
* @throws Exception
*/
public static Object reflectConstructorForInstance(String qualifiedName) throws Exception{
Class<?> clazz = Class.forName(qualifiedName);
Constructor<?> constructor = clazz.getConstructor();
return constructor.newInstance();
}
/**
* 解剖类的构造函数,获取一个参数的构造函数实例
* public Person(String name) {}
* @param <T>:传入的类型
* @param clazz:加载Class对象
* @return T (Object)
*/
public static <T> T reflectConstructorForInstance1(Class<T> clazz) throws Exception{
Constructor<T> constructor = clazz.getConstructor(String.class); //获取无参构造方法对象
return constructor.newInstance("zhangsan"); //创建对象
}
/**
*
* @param qualifiedName
* @param args
* @return
* @throws Exception
*/
public static <T> Object reflectConstructorForInstance1(String qualifiedName,String args) throws Exception{
Class<?> clazz = Class.forName(qualifiedName);
Class<?> clazzArgs = Class.forName(args);
Constructor<?> constructor = clazz.getConstructor(clazzArgs);
return constructor.newInstance("zhangsan");
}
/**
* 反射参数为私有的list的构造方法
* @param clazz 字节码文件生成的Class对象
* @return Class实例对象
* @throws Exception
*/
public static <T> T reflectConstructorForInstance2(Class<T> clazz) throws Exception{
//getDeclaredConstructor:获取私有构造方法对象
Constructor<T> constructor = clazz.getDeclaredConstructor(List.class);
if(!constructor.isAccessible()){ //检查构造函数是否是私有的(false)
constructor.setAccessible(true); //暴力反射
}
return constructor.newInstance(new ArrayList<>());
}
}
二、Java反射通过Class对象方法(Method)对象来进行动态的方法调用。(反射调用Person类的6个方法,一个静态方法,一个私有方法和一个main方法)
package com.java.a.iReflection;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import org.junit.Before;
import org.junit.Test;
import com.java.a.Person;
/**
* 反射类的方法
* @author TS
*
*/
public class IReflectMethod {
Class<?> clazz;
@Before
public void beforeLoadClass() throws Exception{
clazz = Class.forName("com.java.a.Person");
}
/**
* 反射show()
* @throws Exception
*/
@Test
public void test() throws Exception{
Person zhangsan = (Person) clazz.newInstance();
Method method = clazz.getMethod("show");
//举个现实例子:比如说有一个上厕所方法,有一个人类(Person类),要上厕所,要指定实例(如:张三)上厕所,
//所以要传入一个真实的人来调用方法,所以方法要传入一个指定的实例。
method.invoke(zhangsan);
}
/**
* 反射 show(String name,int luckyNum)
* @throws
* @throws Exception
*/
@Test
public void test1 () throws Exception{
Person zhangsan = (Person) clazz.newInstance();
Method method = clazz.getMethod("show", String.class,int.class);
method.invoke(zhangsan, "张三",47);
}
/**
* 反射 show(String name,int[] luckyNum)
* @throws
* @throws Exception
*/
@Test
public void test2 () throws Exception{
Person zhangsan = (Person) clazz.newInstance();
Method method = clazz.getMethod("show", String.class,int[].class);
Class<?> clazz[] = (Class<?>[]) method.invoke(zhangsan, "张三",new int[]{1,2,3});
System.out.println(clazz[0]);
}
/**
* 反射 私有的 private show(InputStream in)
* @throws
* @throws Exception
*/
@Test
public void test3 () throws Exception{
Person zhangsan = (Person) clazz.newInstance();
Method method = clazz.getDeclaredMethod("show", InputStream.class);
if(!method.isAccessible()){
method.setAccessible(true);
}
method.invoke(zhangsan,new FileInputStream("D://test.txt"));
}
/**
*反射静态方法: public static void show(int num)
*
*/
@Test
public void test4() throws Exception{
Method method = clazz.getMethod("show", int.class);
method.invoke(null, 48);
}
/**
* 反射main方法
* Jdk1.4要前兼容Jdk1.5
* @param args
*/
@Test
public void test5() throws Exception{
Method method = clazz.getMethod("main", String[].class);
method.invoke(null, new Object[]{new String[]{"aa","bb"}});
method.invoke(null, (Object)new String[]{"aa","bb"});
}
}
三、Java反射通过Class对象属性(Field)对象来进行属性的调用和赋值
package com.java.a.iReflection;
import java.lang.reflect.Field;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.java.a.Person;
/**
* Java反射类的字段
* 反射Person类的:name,age,list字段
* @author TS
*
*/
public class IReflectField {
Class<?> clazz;
@Before
public void beforeLoadClass() throws Exception{
clazz = Class.forName("com.java.a.Person");
}
/**
* Person-->public myPublic字段
* @throws Exception
*/
@Test
public void test() throws Exception{
Person person = (Person) clazz.newInstance();
Field field = clazz.getField("myPublic"); //获取指定的字段
String name = (String) field.get(person); //指定对象调用字段
Class<?> type = field.getType(); //获取字段类型
System.out.println(type);
System.out.println(name);
//设置字段的值
field.set(person, "newPublic");
System.out.println(person.myPublic);
}
/**
* Person-->private name字段
* @throws Exception
*/
@Test
public void test1() throws Exception{
Person person = (Person) clazz.newInstance();
Field field = clazz.getDeclaredField("name");
if(!field.isAccessible()){
field.setAccessible(true); //暴力反射
}
String name = (String) field.get(person);
System.out.println(name);
}
/**
* Person-->private list字段
* @throws Exception
*/
@Test
public void test2() throws Exception{
Person person = (Person) clazz.newInstance();
Field field = clazz.getDeclaredField("list");
if(!field.isAccessible()){
field.setAccessible(true);
}
List<?> list = (List<?>) field.get(person);
System.out.println(list);
}
}