反射
一.何为反射
反射是一种机制,通过反射机制可以动态实例化对象,调用方法,读写属性,构造函数等等
二.获取类对象,主要有三种方式:
注意:所有的反射代码都是从获取类对象开始的
1)类名.class;
2)对象名.getClass();
3)Class.forName(全限定名/全路径名);
全限定名/全路径名=包名+类名
三.具体请看案例演示:
准备一个学生实体类
package com.zking.reflect.entity;
public class Student{
private String sid;
private String sname;
public Integer 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());
}
}
案例演示
package com.zking.reflect.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.zking.reflect.entity.Student;
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
/**
* 何为反射?
* 反射是一种机制,通过反射机制动态的实例化对象,调用方法,构造函数,读写属性
*/
/**
* 获取类对象主要有三种方式:
* 注意:一切反射相关的代码都从获取类对象开始
* 1.类名.class
* 2.对象名.getClass()
* 3.Class.forName()
*/
//1.类名.class
//Class cla= Student.class;
//2.对象名.getClass()
// Student stu=new Student();
// Class cla = stu.getClass();
//3.Class.forName()
Class cla = Class.forName("com.zking.reflect.entity.Student");
//拓展:比较传统的实例化方式与反射的实例化的方式异同
/**
* 传统的实例化方式:
* 当实体类有或没有无参构造都可以实例化,但是当有有参构造的时候一定要有无参构造
*/
// Student stu=new Student();
/**
* 反射的实例化方式:
* 当实体类中没有无参构造的时候,反射是无法实例化对象的 会出现 InstantiationException 实例化异常
*/
Student stu = (Student) cla.newInstance();
/*System.out.println("类的全路径名:"+cla.getName());
System.out.println("类名:"+cla.getSimpleName());
System.out.println("类的访问修饰符:"+cla.getModifiers());
System.out.println("类的包名:"+cla.getPackage());*/
/**
* 通过类获取属性
* 1.获取单个属性 (只能得到公共的) getField
* 2.获取单个属性(公共的,私有的,受保护的等等) getDeclaredField
* 注意:一定要设置访问权限!!! 否则会出现没有与之匹配的属性异常NoSuchFieldException
* 3.获取所有属性 getDeclaredFields
*/
//获取 公共的 单个属性
// Field field=cla.getField("age");
//获取 公共的,私有的,受保护的等等 单个属性(即以描述的所有属性之一)
// Field field = cla.getDeclaredField("sname");
//当需要访问除公开的之外其他的属性时请设置访问权限
// field.setAccessible(true);
//获取所有已描述的属性 当前对象有三个属性
/*Field[] fields = cla.getDeclaredFields();
for (Field field : fields) {
System.out.println("属性名:"+field.getName());
System.out.println("属性类型:"+field.getType());
System.out.println("属性的访问修饰符:"+field.getModifiers());
}*/
//给属性设置值和获取值
// Field field = cla.getDeclaredField("sname");
//若属性为除公共的以外类型,请一定要设置 属性的访问权限
// field.setAccessible(true);
//设置值
// field.set(stu, "梅子");
//获取值
// Object sname = field.get(stu);//获取该学生对象的属性之一 sname
// System.out.println("学生名:"+sname);
/**
* 根据类得到方法
* 首先,方法的类型主要有四种,分别为:无参无返回,无参有返回,有参无返回,有参有返回
* 1.获取单个公共的方法
* 2.获取单个 (公共的,私有的,受保护的等等) 的方法 在访问请一定要设置访问权限 否则会报 没有与之匹配的方法异常 NoSuchMethodException
* 3.获取所有的公共的方法 没必要 作用不大...
* 4.获取所有的已描述的方法 好像还不错
*/
//1.获取单个公共的方法 第一参数为方法名,第二个参数为:可变参数
// Method method = cla.getMethod("getSid", null);
//在对应的对象实体类中 调用方法 invoke 并返回对应的返回值
// Object invoke = method.invoke(stu, null);
// System.out.println(invoke);//当前对象返回为空 因为没有值
//2.获取单个 (公共的,私有的,受保护的等等) 的方法
// Method method = cla.getDeclaredMethod("add",Integer.class,Integer.class);
//当方法类型是除公共的以外类型时 请一定要设置方法的访问权限
// method.setAccessible(true);
//调用方法
// Object invoke = method.invoke(stu,15,1);
// System.out.println(invoke);
//3.获取类中所有的公共方法
// Method[] methods = cla.getMethods();
//4.获取所有的已描述的方法 一定要设置方法的访问权限
/*Method[] methods = cla.getDeclaredMethods();
for (Method method : methods) {
System.out.println("方法名:"+method.getName());
System.out.println("方法修饰符:"+method.getModifiers());
System.out.println("方法的返回类型:"+method.getReturnType());
}*/
/**
* 根据类得到构造函数
* 套路........
*/
//1.获取单个公共的构造函数
// Constructor con = cla.getConstructor(null);
//2.获取指定的单个除公共的之外的其他类型的构造函数 同样的参数为构造函数的类型
//也请注意要设置构造函数的访问权限
/*Constructor con= cla.getConstructor(String.class);
con.setAccessible(true);
con.newInstance("p001");*/
//3.获取所有的构造函数 公共的
/*Constructor[] con = cla.getConstructors();
for (Constructor c : con) {
System.out.println("名字:"+c.getName());
System.out.println("访问修饰符:"+c.getModifiers());
System.out.println("参数个数:"+c.getParameterCount());
}*/
/**
* 根据类得到类的实现接口列表
*/
Class[] interfaces = cla.getInterfaces();
for (Class c : interfaces) {
System.out.println("接口名称"+c.getName());
}
}
}