反射
已知的对象可以直接创建对象
Student类:
class Student{
private String name;
public int age;
public Student(String name, int age){
this.name = name;
this.age = age;
}
public Student(){
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
private void ageAdd(){
this.age++;
}
@Override
public String toString() {
return "name: " + this.name + " age: " + this.age;
}
}
// 直接创建对象
Student student1 = new Student("redarm",10);
System.out.println(student1.toString());
如果是在运行时才知道对象,那么可以利用反射创建对象
java编译后每个对象都会生成一个字节码文件,反射可以利用字节码文件在运行时创建对象,可以拿到任意一个类的属性,方法
利用反射创建对象,获取类的信息
package com.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @Author redarm
* @Date 2020/5/10 1:20 下午
**/
public class Test {
public static void main(String[] args) throws Exception{
// 反射
// 得到对象字节码的两种方式
Class student2 = Student.class;
//Class two = Class.forName("Student");
// 得到对象的构造器然后调用构造器创建一个新的实例
Constructor constructor = student2.getConstructor(String.class, int.class);
Object o = constructor.newInstance("name",1);
// 直接创建对象
//Object o = student2.newInstance();
System.out.println(o.toString());
// 拿到对象的setname方法, 调用方法改变对象 o 的名字
Method init = student2.getMethod("setName", String.class);
init.invoke(o,"changedName");
System.out.println(o.toString());
// 拿到对象的公有属性
Field[] fields = student2.getFields();
for (Field field : fields){
System.out.println(field.toString());
}
// 对象的方法
Method[] methods = student2.getMethods();
for (Method method : methods){
System.out.println(method.toString());
}
// 对象的构造器
Constructor[] constructors = student2.getConstructors();
for (Constructor constructor1: constructors){
System.out.println(constructor1.toString());
}
}
}
输出所有成员变量的权限,属性,名字,包括private:
Class student = Class.forName("com.reflection.Student");
Field[] fields = student.getDeclaredFields();
for (Field field : fields){
System.out.println(field.getModifiers());
System.out.println(field.getName());
System.out.println(field.getType());
}
输出所有方法的信息,包括private:
Class student = Class.forName("com.reflection.Student");
Method[] methods = student.getDeclaredMethods();
for (Method method : methods){
System.out.println(method.getModifiers());
System.out.println(method.getName());
System.out.println(method.getTypeParameters());
}
利用反射访问私有方法
public static void main(String[] args) throws Exception{
Class studentClass = Class.forName("com.reflection.Student");
Object student = studentClass.newInstance();
Method method = studentClass.getDeclaredMethod("ageAdd");
method.setAccessible(true);
System.out.println(student.toString());
method.invoke(student);
System.out.println(student.toString());
}
invoke方法参数:调用方法的对象,方法参数
利用反射访问并直接修改私有属性
public static void main(String[] args) throws Exception{
Class studentClass = Class.forName("com.reflection.Student");
Object student = studentClass.newInstance();
System.out.println(student.toString());
Field field = studentClass.getDeclaredField("name");
field.setAccessible(true);
field.set(student,"newName");
System.out.println(student.toString());
}
拿到属性,设置允许访问,修改属性