Java基础-反射

   日期:2020-07-06     浏览:88    评论:0    
核心提示:前言疯狂复习基础ing~最近复习的Java基础反射做了应该总结,果然反射不只有那么一点点东西,多的是精髓!最重要的是最后推荐的那两篇文章,写的非常非常好!!反射1.反射的原理Java反射机制就是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意方法和属性;这种动态获取信息以及动态调用对象的功能称为Java语言的反射机制粗略的理解:反射就是在程序运行时,能够动态的操作类的成员。2.反射的用途在日常的第三方应用开发过程中,经常会遇到某个类

前言

疯狂复习基础ing~
最近复习的Java基础反射做了应该总结,果然反射不只有那么一点点东西,多的是精髓!
最重要的是最后推荐的那两篇文章,写的非常非常好!!

反射

1.反射的原理

Java反射机制就是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意方法和属性;这种动态获取信息以及动态调用对象的功能称为Java语言的反射机制

粗略的理解:反射就是在程序运行时,能够动态的操作类的成员。

2.反射的用途

在日常的第三方应用开发过程中,经常会遇到某个类的成员变量、方法或是私有的或是只对系统应用开发,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或方法,框架的底层就用到了很多反射相关的操作。

3.反射机制的相关类

与Java反射相关的类如下

类名 用途
Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Field类 代表类的成员变量(成员变量也称为类的属性)
Method类 代表类的方法
Constructor类 代表类的构造方法

3.1.Class类

Class代表类的实体,在运行的Java应用程序中表示类和接口。在这个类中提供类很多有用的方法。

  • 获取类相关的方法
方法 用途
asSubclass(Class clazz) 把传递的类的对象转换成代表其子类的对象
Cast 把对象转换成代表类或是接口的对象
getClassLoader() 获得类的加载器
getClasses() 返回一个数组,数组中包含该类中所有公共类和接口类的对象
getDeclaredClasses() 返回一个数组,数组中包含该类中所有类和接口类的对象
forName(String className) 根据类名返回类的对象
getName() 获得类的完整路径名字
newInstance() 创建类的实例
getPackage() 获得类的包
getSimpleName() 获得类的名字
getSuperclass() 获得当前类继承的父类的名字
getInterfaces() 获得当前类实现的类或是接口
  • 获取类中属性相关的方法
方法 用途
getField(String name) 获得某个公有的属性对象
getFields() 获得所有公有的属性对象
getDeclaredField(String name) 获得某个属性对象
getDeclaredFields() 获得所有属性对象
  • 获取类中注解的相关方法
方法 用途
getAnnotation(Class annotationClass) 返回该类中与参数类型匹配的公有注解对象
getAnnotations() 返回该类所有的公有注解对象
getDeclaredAnnotation(Class annotationClass) 返回该类中与参数类型匹配的所有注解对象
getDeclaredAnnotations() 返回该类所有的注解对象
  • 获取类中构造器相关的方法
方法 用途
getConstructor(Class…<?> parameterTypes) 获得该类中与参数类型匹配的公有构造方法
getConstructors() 获得该类的所有公有构造方法
getDeclaredConstructor(Class…<?> parameterTypes) 获得该类中与参数类型匹配的构造方法,包含私有
getDeclaredConstructors() 获得该类所有构造方法
  • 获取类中方法的相关方法
方法 用途
getMethod(String name, Class…<?> parameterTypes) 获得该类某个公有的方法
getMethods() 获得该类所有公有的方法
getDeclaredMethod(String name, Class…<?> parameterTypes) 获得该类某个方法
getDeclaredMethods() 获得该类所有方法
  • 类中其他重要的方法
方法 用途
isAnnotation() 如果是注解类型则返回true
isAnnotationPresent(Class<? extends Annotation> annotationClass) 如果是指定类型注解类型则返回true
isAnonymousClass() 如果是匿名类则返回true
isArray() 如果是一个数组类则返回true
isEnum() 如果是枚举类则返回true
isInstance(Object obj) 如果obj是该类的实例则返回true
isInterface() 如果是接口类则返回true
isLocalClass() 如果是局部类则返回true
isMemberClass() 如果是内部类则返回true

3.2.Field类

Field代表类的成员变量对象(成员变量也称为类的属性)

方法 用途
equals(Object obj) 属性与obj相等则返回true
get(Object obj) 获得obj中对应的属性值
set(Object obj, Object value) 设置obj中对应属性值
getName() 获取类中属性的名字

3.3.Method类

Method代表类的方法

方法 用途
invoke(Object obj, Object… args) 传递object对象及参数调用该对象对应的方法

3.4.Constructor类

Constructor代表类的构造方法

方法 用途
newInstance(Object… initargs) 根据传递的参数创建类的对象

4.反射的前提

通过字节码获取class对象

4.1.获取类的Class对象的方式

1.通过类的全路径名的字符串获取class对象

//例如
Class clazz = Class.forName("com.scholarTang.po.UserPo")

2.通过类名.class获取class对象

//例如
Class clazz = UserPo.class

3.通过类的实例获取父类的class对象

//例如
Class clazz = new UserPo().getClass();

4.通过子类的实例获取父类的类对象

//例如
UserPo user = new User();
Class userClazz = user.getClass();
Class supClazz = userClazz.getSuperclass();

5.反射操作

1.通过反射获取目标类的类对象

2.通过类对象获取目标类中的构造方法对象,通过构造方法对象创建目标类对象

3.通过类对象获取目标类中的成员变量对象,在指定对象obj中将此 成员变量对象表示的成员变量设置为指定的新值

4.通过类对象获取目标类中的指定方法对象,调用该方法

5.通过类对象获取目标类中的注解,获取注解中的参数信息

5.1.准备

准备一个目标类

package com.scholarTang.demo;



public class Programmer {
  
  private String id;
  
  private String name;
  
  private Integer age;
  
  private String sex;
  
  private Integer workExperience;

  public String work(String content){
    return this.name + "正在"+content;
  }

  private String learning(String content){
    return this.name + "正在" + content;

  }

  //空参构造函数.......
  //有参构造函数.......
  //Get、Set.......
  //toString.......

}

自定义注解类

package com.scholarTang.demo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target({ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Deprecated
public @interface ClassDescribe {
     String describe() default "";
}

5.2.反射操作

1.通过反射获取目标类的类对象

Class<?> programmerClazz = Class.forName("com.scholarTang.demo.Programmer");
2.通过类对象获取目标类中的构造方法对象,通过构造方法对象创建目标类对象

Constructor<?> constructor = programmerClazz.getConstructor(String.class,String.class,Integer.class,String.class,Integer.class);

Object obj = constructor.newInstance("CXY001","忙碌的指尖",20,"男",1);

System.out.println(obj);
3.通过类对象获取目标类中的成员变量对象,在指定对象obj中将此 成员变量对象表示的成员变量设置为指定的新值

Field[] fields = programmerClazz.getDeclaredFields();
for (Field field : fields) {
	
  field.setAccessible(true);
  
  System.out.print(field.getName() + ":" + field.get(obj) + " ");
}
4.通过类对象获取目标类中的指定方法对象,调用该方法

//getMethod() 获取类对象中指定的公有方法对象,方法有两个构造函数:第一个是方法的名字,第二个是方法的参数类型
Method workMethodObj = programmerClazz.getMethod("work", String.class);
//调用类对象中的这个方法,不管方法是否有返回值,invoke()方法的返回值都会是Object
Object invoke = workMethodObj.invoke(obj, "写代码");
System.out.println(invoke);
//获取类对象中指定的方法,不管是公有的还是私有的都可以被获取到
// Method learningMethodObj = programmerClazz.getDeclaredMethod("learning", String.class);
//如果是私有的方法要对其进行使用需要对其就行暴力反射
// learningMethodObj.setAccessible(true);
// Object invoke = learningMethodObj.invoke(obj, "学习反射");
// System.out.println(invoke);
5.通过类对象获取目标类中的注解,获取注解中的参数信息

ClassDescribe annotation = programmerClazz.getAnnotation(ClassDescribe.class);
if (annotation != null){
  System.out.println(annotation.describe());
}

6.深度好文推荐

以上的内容我只是描述了反射是如何使用的,并没有描述太多真正的关于发射的内涵知识。

但是在复习反射的过程中我也查了比较多的资料,譬如下两篇把反射的描述淋漓尽致,自叹不如写不出这么有深度的文章,但是好的文章应该被更多人看到!

学习java应该如何理解反射?

为什么要反射?

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服