Java 反射机制

简介: Java 反射机制

什么是反射:



对于任何一个类,我们都能知道他有哪些方法。对于任何一个对象我们都可以调用他的任意一个方法和属性,这种动态的获取信息以及动态的调用对象的方法就称为java的反射机制。形象一点说,任何一个类或者对象,对我们来说都是透明的,想要啥直接拿就可以。


首先列出我们要反射的类:


public class Person {
  int age;
  String name;
  private String email;
  public Person(int age, String name) {
  this.age = age;
  this.name = name;
  }
  public Person(int age){};
  public Person(){};
  private String getEmail() {
  System.out.println("我是getEmail");
  return email;
  }
  private void setEmail(String email) {
  this.email = email;
  }
  public int getAge() {
  return age;
  }
  public void setAge(int age) {
  this.age = age;
  }
  public String getName() {
  return name;
  }
  public void setName(String name) {
  System.out.println("我是setName");
  this.name = name;
  }
}


要想对一个类进行反射,就必须获取他的字节码字节码。有三种形式:


//第一种
      Class<?> c1 =new Person().getClass();
      //第二种
      Class<?> c2 = Person.class;
      //第三种,要加包名
      try {
    Class<?> c3 = Class.forName("one.Person");
  } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }


通过反射获取类中的所有构造器


//获取类中的所有构造器
      Constructor<?>[] con = c1.getConstructors();
      System.out.println("共"+con.length+"构造器");
      for (int i = 0; i < con.length; i++) {
      System.out.println("第"+i+"个构造参数");
      //获取构造器参数类型
    Class[] paramenter = con[i].getParameterTypes();
    for (int j = 0; j < paramenter.length; j++) {
    //打印构造器参数
    System.out.print(paramenter[j].getName()+"   ");
    }
    System.out.println();
  }


结果如下:


共3构造器
第0个构造参数
第1个构造参数
int   
第2个构造参数
int   java.lang.String


一个无参,还有两个有参构造。


通过获取的构造器进行实例化


try {
      Person per1 = (Person) con[0].newInstance();
      Person per2 = (Person) con[1].newInstance(20);
      Person per3 = (Person) con[2].newInstance(19,"lv");
  } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }


通过反射获取类中的属性


Person per1 = null,per2 = null,per3= null;
      try {
       per1 = (Person) con[0].newInstance();
       per2 = (Person) con[1].newInstance(20);
       per3 = (Person) con[2].newInstance(19,"lv");
  } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  } 
      //获取某个对象内的某个字段
      try {
    Field f = c1.getDeclaredField("email"); //或取私有属性
    //对私有字段的访问取消检查
    f.setAccessible(true);
    //修改该对象的emal字段
    f.set(per3, "emal@qq.com");
  } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
      //获取当前类的所有属性类型和值
      Field[] field = c1.getDeclaredFields();
      //对私有字段的访问取消检查
      Field.setAccessible(field, true);
      for (int i = 0; i < field.length; i++) {
    try {
    System.out.println("属性名:"+field[i].getName()+"属性类型:"
      +field[i].getType()+"属性值:"+field[i].get(per3));
    } catch (Exception e) {
    e.printStackTrace();
    }
  }


结果如下:


属性名:age属性类型:int属性值:19
属性名:name属性类型:class java.lang.String属性值:lv
属性名:email属性类型:class java.lang.String属性值:emal@qq.com


注意:取消安全性检查后才可以访问私有属性


通过反射获取类中的方法并运行


//获取全部方法
      Method[] methods = c1.getDeclaredMethods();
      for (int i = 0; i < methods.length; i++) {
    System.out.println("方法名称:"+methods[i].getName()+
      " 返回值类型 :"+methods[i].getReturnType()+
      " 方法参数:"+methods[i].getParameterTypes());
  } 
      //获取无参私有方法
      try {
    Method method = c1.getDeclaredMethod("getEmail");
    //对私有字段取消安全检查
    method.setAccessible(true);
    System.out.println("私有方法名称:"+method.getName()+" 返回值类型:"
    +method.getReturnType().getName());
    //调用无参的私有方法
    method.invoke(per3);//即getEmail方法
  } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
      //获取有参方法
      try {
    Method meth = c1.getDeclaredMethod("setName", String.class);
    //调用有参方法
    meth.invoke(per3, "我是Name");//即setName方法
  } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }


结果如下:


方法名称:main 返回值类型 :void 方法参数:[Ljava.lang.Class;@6d06d69c
方法名称:getName 返回值类型 :class java.lang.String 方法参数:[Ljava.lang.Class;@7852e922
方法名称:setName 返回值类型 :void 方法参数:[Ljava.lang.Class;@4e25154f
方法名称:setEmail 返回值类型 :void 方法参数:[Ljava.lang.Class;@70dea4e
方法名称:getAge 返回值类型 :int 方法参数:[Ljava.lang.Class;@5c647e05
方法名称:setAge 返回值类型 :void 方法参数:[Ljava.lang.Class;@33909752
方法名称:getEmail 返回值类型 :class java.lang.String 方法参数:[Ljava.lang.Class;@55f96302
私有方法名称:getEmail 返回值类型:java.lang.String
我是getEmail
我是setName


总结一下:

这些 只是最基本的反射,更多的使用方法还是需要去查api。其实反射是非常重要的。我们还是有必要去掌握它。


若有错误,还请指出,谢谢


相关文章
|
3月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
132 2
|
3月前
|
Java 编译器
探索Java中的异常处理机制
【10月更文挑战第35天】在Java的世界中,异常是程序运行过程中不可避免的一部分。本文将通过通俗易懂的语言和生动的比喻,带你了解Java中的异常处理机制,包括异常的类型、如何捕获和处理异常,以及如何在代码中有效地利用异常处理来提升程序的健壮性。让我们一起走进Java的异常世界,学习如何优雅地面对和解决问题吧!
|
2月前
|
Java 开发者
Java中的异常处理机制深度剖析####
本文深入探讨了Java语言中异常处理的重要性、核心机制及其在实际编程中的应用策略,旨在帮助开发者更有效地编写健壮的代码。通过实例分析,揭示了try-catch-finally结构的最佳实践,以及如何利用自定义异常提升程序的可读性和维护性。此外,还简要介绍了Java 7引入的多异常捕获特性,为读者提供了一个全面而实用的异常处理指南。 ####
98 20
|
2月前
|
Java 程序员
深入理解Java异常处理机制
Java的异常处理是编程中的一块基石,它不仅保障了代码的健壮性,还提升了程序的可读性和可维护性。本文将深入浅出地探讨Java异常处理的核心概念、分类、处理策略以及最佳实践,旨在帮助读者建立正确的异常处理观念,提升编程效率和质量。
149 1
|
2月前
|
Java 开发者 UED
深入探索Java中的异常处理机制##
本文将带你深入了解Java语言中的异常处理机制,包括异常的分类、异常的捕获与处理、自定义异常的创建以及最佳实践。通过具体实例和代码演示,帮助你更好地理解和运用Java中的异常处理,提高程序的健壮性和可维护性。 ##
74 2
|
2月前
|
Java 数据库连接 开发者
Java中的异常处理机制:深入解析与最佳实践####
本文旨在为Java开发者提供一份关于异常处理机制的全面指南,从基础概念到高级技巧,涵盖try-catch结构、自定义异常、异常链分析以及最佳实践策略。不同于传统的摘要概述,本文将以一个实际项目案例为线索,逐步揭示如何高效地管理运行时错误,提升代码的健壮性和可维护性。通过对比常见误区与优化方案,读者将获得编写更加健壮Java应用程序的实用知识。 --- ####
|
3月前
|
运维 Java 编译器
Java 异常处理:机制、策略与最佳实践
Java异常处理是确保程序稳定运行的关键。本文介绍Java异常处理的机制,包括异常类层次结构、try-catch-finally语句的使用,并探讨常见策略及最佳实践,帮助开发者有效管理错误和异常情况。
167 6
|
2月前
|
开发框架 安全 Java
Java 反射机制:动态编程的强大利器
Java反射机制允许程序在运行时检查类、接口、字段和方法的信息,并能操作对象。它提供了一种动态编程的方式,使得代码更加灵活,能够适应未知的或变化的需求,是开发框架和库的重要工具。
88 4
|
2月前
|
Java 程序员 UED
深入理解Java中的异常处理机制
本文旨在揭示Java异常处理的奥秘,从基础概念到高级应用,逐步引导读者掌握如何优雅地管理程序中的错误。我们将探讨异常类型、捕获流程,以及如何在代码中有效利用try-catch语句。通过实例分析,我们将展示异常处理在提升代码质量方面的关键作用。
59 3
|
3月前
|
安全 Java 数据安全/隐私保护
有哪些场景不适合使用Java反射机制
Java反射机制虽强大,但并非万能。在性能要求极高、安全性严格控制、类结构复杂多变或对象创建频繁的场景下,使用反射可能带来性能下降、安全风险增加等问题,应谨慎选择。
95 11