反射是框架设计的灵魂
(使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))
1.什么是反射?
反射是java语言的一种机制,利用反射机制动态的实例化对象(构造函数)、读写属性、调用方法。
反射就是把java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。(其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)
2. 类类
所有狗 狗类 Dog 狗对象 二哈
所有猫 猫类 Cat 猫对象 肥波
所有类 类类 java.lang.Class 类对象 特定类
3.如何得到类对象
一切反射相关的代码都从获得类对象开始
3种获取方式:
2.1 类名.class;
2.2 对象名.getClass();
2.3 Class.forName(全限定名/全路径名)(最常用)
注1:ClassNotFoundException(类名错|少jar包)
注2:同一类的、类对象只会创建一个
package com.zking.reflection;
import java.io.Serializable;
public class Student implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1603085686704653688L;private String sid;
private String sname;
public Integer age;
public static final String path ="";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());
}@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]";
}
}
4.根据类得到类名(全限定名/全路径名)
1)cName.getName(); -->获取全限定名
2)cName.getSimpleName(); -->获取类名
3)cName.getPackage(); -->获取包名
//java反射 是Java中的一个重要的机制
//它可以动态的实例化对象,读写属性,调用方法
//一切反射相关的代码都从获得类对象开始
//活动类对象的方式
//1.类名.class Student stu = new Student();
Class clazz = Student.class;
System.out.println(clazz);
System.out.println("----------------------");
//2.对象名.getClass();
Student stu = new Student();
Class clazz1 = stu.getClass();
System.out.println(clazz1);
System.out.println("----------------------");
//3.Class.forName(全限定名)
Class clazz2 = Class.forName("com.zking.reflection.Student");
System.out.println(clazz2);
System.out.println(clazz==clazz1);
System.out.println(clazz.getSimpleName());//类名
System.out.println(clazz.getTypeName());//获取全限定名
System.out.println(clazz.getPackage());//获取包名
5.根据类得到类的属性
Field field=cla.getField(“属性名”);
field.getName(); -->获取属性名
filed.getType(); -->获取属性类型
field.getModifiers(); -->获取属性访问修饰符
field.set(Object,Object); -->设置属性值,参数1:要设置属性所在对象;参数2:要设置的值;
field.get(Object); -->获取属性值,参数:要获取属性值的对象
clazz.getDeclaredField(“属性名”); -->获取单个属性(私有、公有、受保护、默认、静态)
clazz.getDeclaredFields(); -->获取所有属性(私有、公有、受保护、默认、静态)
6.根据类得到类的方法
//无参无返回、无参有返回、有参无返回、有参有返回
cla.getMethod(); -->获取单个公有方法
cla.getDeclaredMethod(); -->获取当个方法(包括私有、受保护、默认、公有)
cla.getMethods(); -->获取所有公有方法
cla.getDeclaredMethods(); -->获取所有的方法(包括私有、受保护、默认、公有)
7.根据类得到类的构造方法
cla.getConstrutor(); -->获取单个公有构造方法
cla.getDeclaredConstrutor(); -->获取单个构造方法(包括私有、受保护、默认、公有)
cla.getConstrutors(); -->获取所有的公有构造方法
cla.getDeclaredConstrutors(); -->获取所有的构造方法(包括私有、受保护、默认、公有)
8.根据类得到类的实现接口列表
Class[] interface=cla.getInterfaces(); -->获取类对象中所有实现接口列表
//3.Class.forName(全限定名)
Class clazz = Class.forName("com.zking.reflection.Student");
// //实例化对象
Student stu = (Student)clazz.newInstance();
//
System.out.println(stu);
//通过构造方法实例化对象
//1.获取无参公有构造方法对象
Constructor Constructor = clazz.getConstructor();
//2.实例化对象
Object obj =Constructor.newInstance();
System.out.println(obj);
Student stu1 = new Student("001");
System.out.println(stu1);
//获取有参公有构造方法对象
Constructor constructor = clazz.getConstructor(String.class,String.class);
//实例化对象
Object obj1 = constructor.newInstance("s666","萨达");
System.out.println(obj1);
//获取私有有参构造方法对象
Constructor constructor1 = clazz.getDeclaredConstructor(Integer.class);
//如果是私有构造方法 必须打开方法的访问限制
constructor1.setAccessible(true);
//3.Class.forName(全限定名)
Class clazz = Class.forName("com.zking.reflection.Student");
//获取私有有参构造方法对象
Constructor constructor = clazz.getDeclaredConstructor(Integer.class);
//如果是私有构造方法 必须打开方法的访问限制
constructor.setAccessible(true);
//实例化对象
Object newInstance = constructor.newInstance(111);
System.out.println(newInstance);
结果:
调用Student类私有的构造方法创建一个学生对象
Student [sid=null, sname=null, age=111]
//3.Class.forName(全限定名)
Class clazz = Class.forName("com.zking.reflection.Student");
Student stu = (Student)clazz.newInstance();
//读写属性
//1.获取属性对象
Field field = clazz.getDeclaredField("path");
//2.打开访问限制
field.setAccessible(true);System.out.println(field.getModifiers());
System.out.println(Modifier.STATIC);
System.out.println(Modifier.FINAL);
System.out.println(Modifier.PRIVATE);
结果:调用无参构造方法创建了一个学生对象
25
8
16
2
//3.Class.forName(全限定名)
Class clazz = Class.forName("com.zking.reflection.Student");
//无参
Student stu = (Student)clazz.newInstance();
stu.setSname("dog黄");
//调用方法
//1.获取方法
Method method = clazz.getDeclaredMethod("hello");
//2.打开访问限制
method.setAccessible(true);
//3.调用方法
method.invoke(stu);
结果:
你好!我是dog黄
//3.Class.forName(全限定名)
Class clazz = Class.forName("com.zking.reflection.Student");//有参
Student stu = (Student)clazz.newInstance();
stu.setSname("dog黄");
//调用方法
//1.获取方法
Method method = clazz.getDeclaredMethod("hello",String.class);
//2.打开访问限制
method.setAccessible(true);
//3.调用方法
method.invoke(stu,"吊毛");结果:
吊毛你好!我是dog黄
//3.Class.forName(全限定名)
Class clazz = Class.forName("com.zking.reflection.Student");Student stu = (Student)clazz.newInstance();
//add增加
Method method = clazz.getDeclaredMethod("add",Integer.class,Integer.class);
//2.打开访问限制
method.setAccessible(true);
//3.调用方法
Object object = method.invoke(stu,88,99);
System.out.println(object);8.根据类得到类的实现接口列表
Class[] classes = clazz.getInterfaces();
for (Class class1 : classes) {
System.out.println(class1);
}
结果:
调用无参构造方法创建了一个学生对象
187
interface java.io.Serializable