目录
反射
反射的概念
反射的优点和缺点
优点:
缺点:
解决方案:
Class类
Class类的概念
获取Class对象的三种方法
反射实例化对象
用方法反射调
反射读写属性
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
——————百度百科
反射是Java语言中的一种机制,通过这种机制可以动态地实例化对象、读写属性、调用方法
Class类是一个比较特殊的类,它是反射机制的基础,Class类的对象表示正在运行的Java程序中的类或接口,也就是任何一个类被加载时,即将类的.class文件(字节码文件)读入内存的同时,都自动为之创建一个java.lang.Class对象。Class类没有公共构造方法,其对象是JVM在加载类时通过调用类加载器中的defineClass()方法创建的,因此不能显式地创建一个Class对象。通过这个Class对象,才可以获得该对象的其他信息。
——————百度百科
这里我会写一个学生类为例子
package com.zking.reflex;
public class Student {
private String sid;
private String sname;
public Integer age;
static{
System.out.println("加载进jvm中!");
}
@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]";
}
public Student() {
super();
System.out.println("调用无参构造方法创建了一个学生对象");
}
public Student(String sid) {
super();
this.sid = sid;
System.out.println("调用带一个参数的构造方法创建了一个学生对象");
}
public Student(String sid, String sname) {
super();
this.sid = sid;
this.sname = sname;
System.out.println("调用带二个参数的构造方法创建了一个学生对象");
}
@SuppressWarnings("unused")
private Student(Integer age) {
System.out.println("调用Student类私有的构造方法创建一个学生对象");
this.age = age;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public void hello() {
System.out.println("你好!我是" + this.sname);
}
public void hello(String name) {
System.out.println(name + "你好!我是" + this.sname);
}
@SuppressWarnings("unused")
private Integer add(Integer a, Integer b) {
return new Integer(a.intValue() + b.intValue());
}
}
❤获取的方法
大家注意了,这里我们需要填类的权限命名 ,获取命名的方法如下图片所示:
首先点开学生类(例子), 鼠标右键点击绿色的Student,选择Copy Qualified Name,类的权限命名就拿到了。
然后复制到Class.forName(),的括号里就完成了。
package com.zking.reflex;
public class Demo {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception {
//1.通过 Class.forName(类的权限命名) 获取Class
Class clazz = (Class)Class.forName("com.zking.reflex.Student");
//2.通过 类.class 获取Class
Class clazz02 = Student.class;
//3.通过 对象.getClass() 获取Class
Student stu = new Student();
Class clazz03 = stu.getClass();
System.out.println(clazz);
System.out.println(clazz02);
System.out.println(clazz03);
}
}
运行结果:
获取的值都是一样的。
还是以学生类为例子
//通过反射实例化对象
//1.调用无参构造方法
Constructor c1 = clazz.getConstructor();
Student stu01 = c1.newInstance();
stu01.setSname("纪念品");
System.out.println(stu01);
//2.调用带一个参数的构造方法
Constructor c2 = clazz.getConstructor(String.class);
Student stu02 = c2.newInstance("001");
stu02.setSname("流浪者");
System.out.println(stu02);
//3.调用带两个参数的构造方法
Constructor c3 = clazz.getConstructor(String.class,String.class);
Student stu03 = c3.newInstance("002","小女巫");
System.out.println(stu03);
//4.调用私有的方法
//Declared 可以获取公共的或私有的属性或方法
Constructor c4 = clazz.getDeclaredConstructor(Integer.class);
c4.setAccessible(true);
Student stu04 = c4.newInstance(18);
System.out.println(stu04);
Method method = clazz.getMethod("hello");
stu04.setSname("lihao");
//调用方法
method.invoke(stu04);
Method method02 = clazz.getMethod("hello",String.class);
method02.invoke(stu04, "zengfanyan");
//获取私有方法
Method method03 = clazz.getDeclaredMethod("add",Integer.class, Integer.class);
method03.setAccessible(true);
int rv = (int)method03.invoke(stu04, 1,1);
System.out.println(rv);
Field f = clazz.getField("age");
f.set(stu04, 78);
System.out.println(stu04);
System.out.println(f.get(stu04));
//获取私有属性
Field f01 = clazz.getDeclaredField("sname");
f01.setAccessible(true);
//调用属性
f01.set(stu04, "lihao is hao ren");
System.out.println(stu04);
补充:
Bean对象除了上述获取属性的方法之外,还可以通过BeanUtil.getproperty(对象名,“属性”)的方式获取属性,其原理是先调用类中的公开get属性的方法获取再通过反射机制进行获取
好了,这篇文章就到这里结束了,拜拜!