首页 > 编程语言 >java高级--反射(reflect)

java高级--反射(reflect)

时间:2023-01-11 21:02:15浏览次数:35  
标签:lang java String -- reflect ooyhao Student public


java高级--反射(reflect)_java


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

关注小编微信公众号获取更多资源



标签:lang,java,String,--,reflect,ooyhao,Student,public
From: https://blog.51cto.com/u_12131813/6002850

相关文章

  • 【转】PageOffice——实现Word文档指定内容可编辑,其他内容只读
    pageoffice实现word文件部分区域可编辑依赖word中的书签1.文件在本地打开将需要用户在线编辑的内容设置为数据区域DateRegion(数据区域:word中以PO_开头的书签)注意:书签的......
  • An Introduction to JavaScript
    AnIntroductiontoJavaScriptAnIntroductiontoJavaScriptLet’sseewhat’ssospecialaboutJavaScript,whatwecanachievewithit,andwhatothertechn......
  • 《Spring in action 4》(十一)SSM + Redis
    SSM+Redis文章目录​​SSM+Redis​​​​SpringDataRedis​​​​项目整合​​​​项目结构​​​​InitWebApplication​​​​RootConfig​​​​ServletCofig.xml​......
  • 【Codeforces 173B】 B. Chamber of Secrets
    【Codeforces173B】B.ChamberofSecretshttps://codeforces.com/problemset/problem/173/B题意+分析来自\(OI-wiki\)这题主要难度就是读题...还有注意初始方向......
  • 《Spring in action 4》(十)Spring发送eMail
    Spring发送eMail文章目录​​Spring发送eMail​​​​邮件发送准备​​​​POM文件​​​​配置JavaMailSender​​​​项目结构图​​​​发送简单邮件​​​​发送带有附......
  • 2.Spring组成及扩展
    Spring的组成: SpringBoot  快速开发脚手架  可以快速开发单个微服务,把一个功能单独提取出来就是一个微服务  约定大于配置,主要学习他的配置  学习SpringBoot......
  • 《Spring in action 4》(九)SpringCache
    SpringCache文章目录​​SpringCache​​​​简述​​​​ConcurrentMapCacheManager​​​​切换成RedisCacheManager​​​​SpringCache注解​​​​注解声明规则​​......
  • AIGC 很火,想微调个自己的模型试试看?(不是卖课的)
    去年,我们发布过一篇关于DreamBooth编程马拉松的活动通知,获得了全球社区的广泛关注和参与,中国社区的成员们也对这个活动有非常高的热情。同时我们也收到了后台留言反馈说......
  • 《Spring in action 4》(八)Spring和JDBC操作数据库
    Spring和JDBC操作数据库文章目录​​Spring和JDBC操作数据库​​​​使用JNDI配置数据源​​​​使用JDNI方式访问数据库​​​​1.POM依赖​​​​2.Tomcatcontext.xml......
  • Linux:文件与目录
    目录网络不通畅运维操作规范(运维⼈员==救⽕队员)具体操作:一、etc目录下重要的数据文件1./etc/fstab-filesystemtable系统挂载信息表2./etc/rc.local-此文件中只能存放......