1.获取Class对象的几种方式
/**
* 获取Class对象的三种方式
* 1 Object ——> getClass();
* 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
* 3 通过Class类的静态方法:forName(String className)(常用)
*
*/
Student对象
package com.ooyhao.reflection.bean;
import java.io.Serializable;
public class Student implements Serializable {
public Integer id;
private String name;
private String sex;
private Integer age;
public Student() {}
public Student(String name){
this.name = name;
}
public Student(String name, Integer age){
this.name = name;
this.age = age;
}
public Student(Integer id, String name, String sex, Integer age) {
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
}
protected Student(Integer id,String name){
this.name = name;
}
private Student(Integer id){
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
private String printInfo(String message){
System.out.println("仅仅是为了演示:"+message);
this.name = message;
return message;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
获取Class对象的几种方法
@Test
public void getClassFun() throws ClassNotFoundException {
/**
* 方式一:利用对象的getClass()方法来获取Class对象
* 说明:既然已经有了对象,在通过对象获取Class意义不太(不常用)
* */
Student student = new Student();
Class<?> aClass = student.getClass();
System.out.println(aClass);
/**
* 方式二:利用类的class属性来获取Class对象
* 说明:需要导入完整的包名,依赖性比较强,如果不导入包,则会报编译异常(不常用)
* */
Class<Student> studentClass = Student.class;
System.out.println(studentClass);
/**
* 方式三:利用Class类的forName()方法,通过完整的包名+类名获取Class对象
* 说明:不用导入包名、类名,也不用创建对象(推荐)
* 一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法。
* */
Class<?> forName = Class.forName("com.ooyhao.reflection.bean.Student");
System.out.println(forName);
}
输出结果:
class com.ooyhao.reflection.bean.Student
class com.ooyhao.reflection.bean.Student
class com.ooyhao.reflection.bean.Student
true
true
true
2.获取构造方法并使用
1.获取构造方法:
1).批量的方法:
public Constructor[] getConstructors():所有”公有的”构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
2).获取单个的方法,并调用:
public Constructor getConstructor(Class… parameterTypes):获取单个的”公有的”构造方法:
public Constructor getDeclaredConstructor(Class… parameterTypes):获取”某个构造方法”可以是私有的,或受保护、默认、公有;
调用构造方法:
Constructor–>newInstance(Object… initargs)
2、newInstance是 Constructor类的方法(管理构造函数的类)
api的解释为:
newInstance(Object… initargs)
使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
它的返回值是T类型,所以newInstance是创建了一个构造方法的声明类的新实例对象。并为之调用
案例演示:
@Test
public void testConstructor() throws Exception{
Class<?> aClass = Class.forName("com.ooyhao.reflection.bean.Student");
/*获取所有public修饰的构造器*/
// Constructor<?>[] constructors = aClass.getConstructors();
/*获取所有构造器(private,protected,default,public)*/
Constructor<?>[] constructors = aClass.getDeclaredConstructors();
for (Constructor constructor : constructors){
System.out.println(constructor);
Class[] parameterTypes = constructor.getParameterTypes();
for (Class c : parameterTypes){
System.out.println(c);
}
System.out.println("-----------------");
}
/*获取共有的,无参的构造器*/
Constructor<?> constructor = aClass.getConstructor(null);
//public com.ooyhao.reflection.bean.Student()
System.out.println(constructor);
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(Integer.class);
//private com.ooyhao.reflection.bean.Student(java.lang.Integer)
System.out.println(declaredConstructor);
declaredConstructor.setAccessible(true);//暴力访问(忽略掉访问修饰符)
Object o = declaredConstructor.newInstance(12);
Student student = (Student) o;
//student:Student{id=12, name='null', sex='null', age=null}
System.out.println("student:"+student);
}
运行结果:
private com.ooyhao.reflection.bean.Student(java.lang.Integer)
class java.lang.Integer
-----------------
protected com.ooyhao.reflection.bean.Student(java.lang.Integer,java.lang.String)
class java.lang.Integer
class java.lang.String
-----------------
public com.ooyhao.reflection.bean.Student(java.lang.Integer,java.lang.String,java.lang.String,java.lang.Integer)
class java.lang.Integer
class java.lang.String
class java.lang.String
class java.lang.Integer
-----------------
public com.ooyhao.reflection.bean.Student()
-----------------
public com.ooyhao.reflection.bean.Student(java.lang.String)
class java.lang.String
-----------------
public com.ooyhao.reflection.bean.Student(java.lang.String,java.lang.Integer)
class java.lang.String
class java.lang.Integer
-----------------
public com.ooyhao.reflection.bean.Student()
private com.ooyhao.reflection.bean.Student(java.lang.Integer)
student:Student{id=12, name='null', sex='null', age=null}
3.获取成员变量并调用
/*
* 获取成员变量并调用:
*
* 1.批量的
* 1).Field[] getFields():获取所有的”公有字段”
* 2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
* 2.获取单个的:
* 1).public Field getField(String fieldName):获取某个”公有的”字段;
* 2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
*
* 设置字段的值:
* Field –> public void set(Object obj,Object value):
* 参数说明:
* 1.obj:要设置的字段所在的对象;
* 2.value:要为字段设置的值;
*/
案例演示:
@Test
public void testField() throws Exception{
Class<?> aClass = Class.forName("com.ooyhao.reflection.bean.Student");
System.out.println("----------获取public属性----------");
Field[] fields = aClass.getFields();
for (Field field : fields){
System.out.println(field);
}
System.out.println("----------获取public,default,protected,private属性----------");
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field : declaredFields){
System.out.println(field);
}
/*通过反射设置属性的值*/
System.out.println("------通过反射设置属性的值------");
Object o = aClass.newInstance();
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);
name.set(o,"欧阳浩");
Student student = (Student) o;
System.out.println(student);
}
运行结果:
----------获取public属性----------
public java.lang.Integer com.ooyhao.reflection.bean.Student.id
----------获取public,default,protected,private属性----------
public java.lang.Integer com.ooyhao.reflection.bean.Student.id
private java.lang.String com.ooyhao.reflection.bean.Student.name
private java.lang.String com.ooyhao.reflection.bean.Student.sex
private java.lang.Integer com.ooyhao.reflection.bean.Student.age
------通过反射设置属性的值------
Student{id=null, name='欧阳浩', sex='null', age=null}
4.获取成员方法并调用
/*
* 获取成员方法并调用:
*
* 1.批量的:
* public Method[] getMethods():获取所有”公有方法”;(包含了父类的方法也包含Object类)
* public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
* 2.获取单个的:
* public Method getMethod(String name,Class<?>… parameterTypes):
* 参数:
* name : 方法名;
* Class … : 形参的Class类型对象
* public Method getDeclaredMethod(String name,Class<?>… parameterTypes)
*
* 调用方法:
* Method –> public Object invoke(Object obj,Object… args):
* 参数说明:
* obj : 要调用方法的对象;
* args:调用方式时所传递的实参;
*/
案例演示:
@Test
public void testMethod() throws Exception{
Class<?> aClass = Class.forName("com.ooyhao.reflection.bean.Student");
System.out.println("----------获取public成员方法----------");
Method[] methods = aClass.getMethods();
for (Method method : methods){
System.out.println(method);
}
Method[] declaredMethods = aClass.getDeclaredMethods();
System.out.println("----------获取public,default,protected,private成员方法----------");
for (Method method : declaredMethods){
System.out.println(method);
}
/*获取setName方法*/
System.out.println("----------获取printInfo方法----------");
Method printInfo = aClass.getDeclaredMethod("printInfo", String.class);
System.out.println(printInfo);
// Object o1 = aClass.newInstance();
printInfo.setAccessible(true);//解除私有限定
Object o = aClass.getConstructor().newInstance();
Object ouYang = printInfo.invoke(o, "ouYangHao");
//返回的是对象Student对象。Student{id=null, name='ouYangHao', sex='null', age=null}
System.out.println("对象:"+o);
//返回的是方法的返回值。ouYangHao
System.out.println("方法返回值:"+ouYang);
}
运行结果:
----------获取public成员方法----------
public java.lang.String com.ooyhao.reflection.bean.Student.toString()
public java.lang.String com.ooyhao.reflection.bean.Student.getName()
public java.lang.Integer com.ooyhao.reflection.bean.Student.getId()
public void com.ooyhao.reflection.bean.Student.setName(java.lang.String)
public java.lang.String com.ooyhao.reflection.bean.Student.getSex()
public void com.ooyhao.reflection.bean.Student.setSex(java.lang.String)
public java.lang.Integer com.ooyhao.reflection.bean.Student.getAge()
public void com.ooyhao.reflection.bean.Student.setAge(java.lang.Integer)
public void com.ooyhao.reflection.bean.Student.setId(java.lang.Integer)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
----------获取public,default,protected,private成员方法----------
public java.lang.String com.ooyhao.reflection.bean.Student.toString()
public java.lang.String com.ooyhao.reflection.bean.Student.getName()
public java.lang.Integer com.ooyhao.reflection.bean.Student.getId()
public void com.ooyhao.reflection.bean.Student.setName(java.lang.String)
private java.lang.String com.ooyhao.reflection.bean.Student.printInfo(java.lang.String)
public java.lang.String com.ooyhao.reflection.bean.Student.getSex()
public void com.ooyhao.reflection.bean.Student.setSex(java.lang.String)
public java.lang.Integer com.ooyhao.reflection.bean.Student.getAge()
public void com.ooyhao.reflection.bean.Student.setAge(java.lang.Integer)
public void com.ooyhao.reflection.bean.Student.setId(java.lang.Integer)
----------获取printInfo方法----------
private java.lang.String com.ooyhao.reflection.bean.Student.printInfo(java.lang.String)
仅仅是为了演示:ouYangHao
对象:Student{id=null, name='ouYangHao', sex='null', age=null}
方法返回值:ouYangHao
5.反射调用main方法
@Test
public void testMain() throws Exception {
//1、获取Student对象的字节码
Class<?> aClass = Class.forName("com.ooyhao.reflection.test.MainFun");
//2、获取main方法
Method main = aClass.getMethod("main", String[].class);
System.out.println(main);
//3、调用main方法
main.invoke(null,(Object)new String[]{"a","b","c"});//方法一
String[] args = new String[]{"Java","SpringBoot","SpringCloud","Dubbo","Zookeeper"};
//第一个参数,对象类型,因为方法是static静态的,所以为null可以,
//第二个参数是String数组,这里要注意在jdk1.4时是数组,jdk1.5之后是可变参数
//这里拆的时候将 new String[]{"a","b","c"} 拆成3个对象。。。所以需要将它强转。
main.invoke(null,new Object[]{args});//方法二
}
运行结果:
public static void com.ooyhao.reflection.test.MainFun.main(java.lang.String[])
----------执行main方法----------
main方法参数:[a, b, c]
----------执行main方法----------
main方法参数:[Java, SpringBoot, SpringCloud, Dubbo, Zookeeper]
6.返回跳过泛型检查
@Test
public void testGenetic() throws Exception {
List<String> list = new ArrayList<String>();
list.add("Java");
Class<?> aClass = list.getClass();
Method add = aClass.getMethod("add", Object.class);
add.invoke(list,100);
for (Object o : list){
System.out.println(o);
}
}
运行结果:
Java
100
关注小编微信公众号获取更多资源