Java基础(反射)
一、Java反射机制概述
1.1、概述
反射 -- 目的:使用另外一种方式创建对象,访问属性和调用方法
1.2、反射的应用
应用反射首先配置properties:想改对象的类/创建对象不用重新写,改配置文件就行
创建对象并调用方法一条龙:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;public class MyTest {public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {//Student student = new Student();//student.study();/** 读取配置文件,创建对象并调用方法* */Properties prop = new Properties();prop.load(new FileInputStream("config.properties"));//获取全类名String className = prop.getProperty("class");//获取方法名String methodName = prop.getProperty("method");System.out.println(className);System.out.println(methodName);//获取Class类的对象 -- 代表加载到内存的.class文件Class<?> c = Class.forName(className);//创建对象 -- 调用默认构造方法创建对象Object o = c.newInstance();System.out.println(o instanceof Student);System.out.println(o instanceof Teacher);//获取Method对象 Method method = c.getMethod(methodName, null);//调用方法method.invoke(o,null);}
}
1.3、反射涉及的类:
java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造器
Class -- 代表加载到内存的.class文件,包含类的所有信息 总结:反射操作的前提是得到Class类的对象 Field -- 代表类的属性 -- 通过反射对属性进行操作要先得到该类的对象 Method -- 代表类的方法 -- 通过反射调用方法要先得到该类的对象 Constructor -- 代表类的构造方法 -- 通过反射创建对象要先得到该类的对象
二、Class类及反射的原理:
三、反射相关操作:
3.1、获取Class类的实例(重点)
类名.class效率最高
对象.getClass
Class.forName("全类名") 可能出现异常
import day31.Student;/*
* 反射中涉及到的类
* Class -- 代表加载到内存的.class文件,包含类的所有信息
* 总结:反射操作的前提是得到Class类的对象
* Field -- 代表类的属性 -- 通过反射对属性进行操作要先得到该类的对象
* Method -- 代表类的方法 -- 通过反射调用方法要先得到该类的对象
* Constructor -- 代表类的构造方法 -- 通过反射创建对象要先得到该类的对象
* 获取Class类的对象
* Class.forName(全类名) 全类名 = 包名 + 类名
* 类名.class
* 对象名.getClass()
*
* */
public class MyTest01 {public static void main(String[] args) throws ClassNotFoundException {Class c1 = Class.forName("day31.Student");Class c2 = Student.class;Student s = new Student();Class c3 = s.getClass();/** * */System.out.println(c1 == c2);System.out.println(c1 == c3);System.out.println(c2 == c3);}
}
3.2、创建对象(重点)
要创建类的对象,可以new,不使用new,如何创建?
3.2.1、操作无参数的构造方法
Object newInstance():调用默认构造函数,返回一个对象实例
package day32;import day31.Student;import java.lang.reflect.Constructor;public class MyTest02 {public static void main(String[] args) throws Exception {/** 通过反射创建对象* 1、newInstance() -- 调用默认的构造方法* 2、获取Constructor对象,再去创建对象* *///获取Class类的对象Class c = Class.forName("day31.Student");//通过默认的构造方法创建对象Object o = c.newInstance();System.out.println(o instanceof Student);System.out.println("-----------------------------------");//获取默认的构造方法Constructor constructor1 = c.getConstructor(null);//通过Constructor对象创建Student对象Object o1 = constructor1.newInstance(null);System.out.println(o1 instanceof Student);}
}
3.2.2、操作有参数的构造方法
Constructor<T> getConstructor(Class<?>... parameterTypes):取得本类的指定形参类型的构造器
获取了Constructor对象,再去创建所要类的对象。
package day31;public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}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 void study(){System.out.println("study..");}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
package day32;
import day31.Student;import java.lang.reflect.Constructor;public class MyTest02 {public static void main(String[] args) throws Exception {/** 通过反射创建对象* 1、newInstance() -- 调用默认的构造方法* 2、获取Constructor对象,再去创建对象* *///获取Class类的对象Class c = Class.forName("day31.Student");//通过默认的构造方法创建对象Object o = c.newInstance();System.out.println(o instanceof Student);System.out.println("------------------------------------");//获取默认的构造方法Constructor constructor1 = c.getConstructor(null);//通过Constructor对象创建Student对象Object o1 = constructor1.newInstance(null);System.out.println(o1 instanceof Student);System.out.println("-------------------------------------");//获取全参的构造方法Constructor constructor2 = c.getConstructor(String.class, Integer.class);//通过有参的构造方法创建对象Object o2 = constructor2.newInstance("zs",12);System.out.println(o2 instanceof Student);System.out.println(o2.toString());//默认也调用toString()}
}
3.3、获取运行时类的指定结构(重点)
3.3.1、获取属性
package day32;import java.io.IOException;
import java.lang.reflect.Field;public class MyTest3 {public static void main(String[] args) throws Exception {//获取Class类的对象Class c = Class.forName("day31.Student");//创建Student对象Object o = c.newInstance();//获取Filed类的对象 -- public//Field name = c.getField("name");//private的Field name = c.getDeclaredField("name");//设置其可以访问name.setAccessible(true);//设置属性的值name.set(o,"tom");//获取属性的值System.out.println(name.get(o));}
}
3.3.2、调用方法
package day32;import java.lang.reflect.Method;public class MyTest03 {public static void main(String[] args) throws Exception {//获取Class类的对象Class c = Class.forName("day32.Student");//创建Student的对象Object o = c.newInstance();//获取Method类的对象Method method = c.getMethod("study", String.class);//调用方法method.invoke(o, "Java");}
}