反射概念:将类的各个组成部分封装为其他对象,这就是反射机制
获取class对象的方式:
1.Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象
*多数用于配置文件 将类名定义在配置文件中 读取文件加载类
2.类名.class :通过类名的属性class获取
*用于参数传递
3.对象.getClass() :该方法在object类中定义着
*用于对象的获取字节码的方式
结论:
同一个字节码文件(.Class)再一次程序运行过程中,只会被加载一次,不论通过 哪一种方式获取的class对象都是同一个
获取了class对象之后可以用他的成员变量,构造方法,成员方法,类名
举例:
我现在写好一个学生类:
package fanshe;//只放在fanshe包下面
public class Student {
private int age=18;
private String name;
public String nums;
}
Class<Student> cls1 = Class.forName("fanshe.Student");//使用全类名获取class对象
Class<Student> cls2 = Student.class;//使用类.class获取class对象
Student s=new Student();
Class cls3 = s.getClass();;//使用对象.getClass()获取class对象
这三种方式获取出来的class类对象是同一个
打印结果:
class fanshe.Student
class fanshe.Student
class fanshe.Student
获取class对象的成员变量,构造方法,成员方法,类名,以及使用
1.获取成员变量
Field[] getFields()
getDeclaredField(String name)//
2.获取构造方法
Constructor getConstructor(类)
Constructor[] getConstructors()
3.获取成员方法
Method[] getMethods()
Method getMethod(String name, 类<?>... parameterTypes)
getDeclaredMethod(String name, 类<?>... parameterTypes)
4.获取类名
String getName()
//获取class类对象
Class<Student> cls = Student.class;//使用类.class获取class对象
Field[] fields = cls.getFields();//获取所有Public成员变量
Field[] declaredFields = cls.getDeclaredFields();//获取所有成员变量 不管什么修饰符
//获取成员变量
Student stu=new Student();
stu.setName("小明");//先给对象设置一个名字
Field name = cls.getDeclaredField("name");//获得name成员变量
name.setAccessible(true);//使用暴力反射强制改名
name.get(stu);//调用get方法需要传参,获取谁的name?小明
System.out.println("反射前"+stu);//反射前Student{age=0, name='小明', nums='null'}
name.set(stu,"张三");//调用set方法需要传承,设置谁的name? stu改名为张三
System.out.println("反射后"+stu);//反射后Student{age=0, name='张三', nums='null'}
//获取构造器
Constructor<Student> constructor = cls.getConstructor(int.class,String.class,String.class);//获取构造器
Student ss = constructor.newInstance(18, "李四","001");//传参构造新对象
System.out.println(ss);//Student{age=18, name='李四', nums='001'}
//获取成员方法
Method[] methods = cls.getMethods();//获取所有public成员方法
Method getName = cls.getMethod("getName");//获取方法
//getName.invoke(stu)相当于stu.getName()返回名字
System.out.println("名字是"+getName.invoke(stu));//名字是张三
// Method[] declaredMethods = cls.getDeclaredMethods();//获取那些被public修饰以及带有其他修饰符的方法
//获取类名
System.out.println(cls.getName());//fanshe.Student