JAVA反射机制的学习(2)

简介:

JAVA语言中的反射机制:

Java 运行时 环境中,对于任意一个类,能否知道这个类有哪些属性和方法?
对于任意一个对象,能否调用他的方法?这些答案是肯定的,这种动态获取类的信息,以及动态调用类的方法的功能来源于JAVA的反射。从而使java具有动态语言的特性。
AI 代码解读

JAVA反射机制主要提供了以下功能:

  1.在运行时判断任意一个对象所属的类
  2.在运行时构造任意一个类的对象
  3.在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法)
  4.在运行时调用任意一个对象的方法(*****注意:前提都是在运行时,而不是在编译时)
AI 代码解读

Java 反射相关的API简介:

  位于java。lang。reflect包中
    --Class类:代表一个类
    --Filed类:代表类的成员变量
    --Method类:代表类的方法
    --Constructor类:代表类的构造方法
    --Array类:提供了动态创建数组,以及访问数组的元素的静态方法。该类中的所有方法都是静态方法
AI 代码解读
----Class类
     在 java 的Object类中的申明了数个应该在所有的java类中被改写的methods:
AI 代码解读

hashCode(), equals(),clone(),toString(),getClass()等,其中的getClass()返回一个
Class 类型的对象。

 Class类十分的特殊,它和一般的类一样继承自Object,其实体用以表达java程序运行
AI 代码解读

时的 class和 interface,也用来表达 enum,array,primitive,Java Types 以及关键字void
,当加载一个类,或者当加载器(class loader)的defineClass()被JVM调用,便产生一个Class
对象,

 Class是Reflection起源,针对任何你想探勘的class(类),唯有现为他产生一个Class
AI 代码解读

的对象,接下来才能经由后者唤起为数十多个的反射API。

     Java允许我们从多种途径为一个类class生成对应的Class对象。
          --运用 getClass():Object类中的方法,每个类都拥有此方法 
                                String str="abc";
                                Class cl=str.getClass();

         --运用 Class.getSuperclass():Class类中的方法,返回该Class的父类的Class
         --运用 Class.forName()静态方法:
         --运用 ,Class:类名.class
         --运用primitive wrapper classes的TYPE语法: 基本类型包装类的TYPE,如:Integer.TYPE
                      注意:TYPE的使用,只适合原生(基本)数据类型
----运行时生成instance
AI 代码解读
 想生成对象的实体,在反射动态机制中有两种方法,一个针对无变量的构造方法,一个针对带参数的
AI 代码解读

构造方法,如果想调用带参数的构造方法,就比较的麻烦,不能直接调用Class类中的newInstance()
,而是调用Constructor类中newInstance()方法,首先准备一个Class[]作为Constructor的参数类型。
然后调用该Class对象的getConstructor()方法获得一个专属的Constructor的对象,最后再准备一个
Object[]作为Constructor对象昂的newInstance()方法的实参。

  在这里需要说明的是 只有两个类拥有newInstance()方法,分别是Class类和Constructor
AI 代码解读

Class类中的newInstance()方法是不带参数的,而Constructro类中的newInstance()方法是带参数的
需要提供必要的参数。

例:
AI 代码解读
      Class c=Class.forName("DynTest");
      Class[] ptype=new Class[]{double.class,int.class};
      Constructor ctor=c.getConstructor(ptypr);
      Object[] obj=new Object[]{new Double(3.1415),new Integer(123)};
      Object object=ctor.newInstance(obj);
      System.out.println(object);
AI 代码解读

----运行时调用Method

这个动作首先准备一个Class[]{}作为getMethod(String nameClass[])方法的参数类型,接下来准备一个
AI 代码解读

Obeject[]放置自变量,然后调用Method对象的invoke(Object obj,Object[])方法。

 注意,在这里调用
AI 代码解读

----运行时调用Field内容

变更Field不需要参数和自变量,首先调用Class的getField()并指定field名称,获得特定的Field对象后
AI 代码解读

便可以直接调用Field的 get(Object obj)和set(Object obj,Object value)方法

java 代码
package cn.com.reflection;   
  
import java.lang.reflect.Field;   
import java.lang.reflect.InvocationTargetException;   
import java.lang.reflect.Method;   
  
public class ReflectTester {   
  
    /**  
     * 在这个类里面存在有copy()方法,根据指定的方法的参数去 构造一个新的对象的拷贝  
     * 并将他返回  
     * @throws NoSuchMethodException   
     * @throws InvocationTargetException   
     * @throws IllegalAccessException   
     * @throws InstantiationException   
     * @throws SecurityException   
     * @throws IllegalArgumentException   
     */  
    public Object copy(Object obj) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{   
           
        //获得对象的类型   
        Class classType=obj.getClass();   
        System.out.println("该对象的类型是:"+classType.toString());   
           
        //通过默认构造方法去创建一个新的对象,getConstructor的视其参数决定调用哪个构造方法   
        Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});   
           
        //获得对象的所有属性   
        Field[] fields=classType.getDeclaredFields();   
           
        for(int i=0;i<fields.length;i++{
            //获取数组中对应的属性   
            Field field=fields[i];   
               
            String fieldName=field.getName();   
            String stringLetter=fieldName.substring(0, 1).toUpperCase();   
               
            //获得相应属性的getXXX和setXXX方法名称   
            String getName="get"+stringLetter+fieldName.substring(1);   
            String setName="set"+stringLetter+fieldName.substring(1);   
               
            //获取相应的方法   
            Method getMethod=classType.getMethod(getName, new Class[]{});   
            Method setMethod=classType.getMethod(setName, new Class[]{field.getType()});   
               
            //调用源对象的getXXX()方法   
            Object value=getMethod.invoke(obj, new Object[]{});   
            System.out.println(fieldName+" :"+value);   
               
            //调用拷贝对象的setXXX()方法   
            setMethod.invoke(objectCopy,new Object[]{value});   
               
               
        }   
           
        return objectCopy;   
           
    }   
       
       
    public static void main(String[] args) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {   
        Customer customer=new Customer();   
        customer.setName("hejianjie");   
        customer.setId(new Long(1234));   
        customer.setAge(19);   
           
        Customer customer2=null;   
        customer2=(Customer)new ReflectTester().copy(customer);   
        System.out.println(customer.getName()+" "+customer2.getAge()+" "+customer2.getId());   
           
        System.out.println(customer);   
        System.out.println(customer2);   
           
  
    }   
  
}   
  
  
class Customer{   
       
    private Long id;   
       
    private String name;   
       
    private int age;   
       
       
    public Customer(){   
           
    }   
  
    public int getAge() {   
        return age;   
    }   
  
  
    public void setAge(int age) {   
        this.age = age;   
    }   
  
  
    public Long getId() {   
        return id;   
    }   
  
  
    public void setId(Long id) {   
        this.id = id;   
    }   
  
  
    public String getName() {   
        return name;   
    }   
  
  
    public void setName(String name) {   
        this.name = name;   
    }   
       
}  

java 代码
package cn.com.reflection;   
  
import java.lang.reflect.Array;   
  
public class ArrayTester1 {   
  
    /**  
     * 此类根据反射来创建  
     * 一个动态的数组   
     */  
    public static void main(String[] args) throws ClassNotFoundException {   
           
        Class classType=Class.forName("java.lang.String");   
           
        Object array= Array.newInstance(classType,10);  //指定数组的类型和大小   
           
         //对索引为5的位置进行赋值   
        Array.set(array, 5, "hello");   
           
        String s=(String)Array.get(array, 5);   
           
        System.out.println(s);   
           
           
        //循环遍历这个动态数组   
        for(int i=0;i<((String[])array).length;i++){   
               
            String str=(String)Array.get(array, i);   
               
            System.out.println(str);   
        }   
  
    }   
  
}   
AI 代码解读

本文出自seven的测试人生公众号最新内容请见作者的GitHub页:http://qaseven.github.io/

目录
打赏
0
0
0
0
176
分享
相关文章
理解的Java中SPI机制
本文深入解析了JDK提供的Java SPI(Service Provider Interface)机制,这是一种基于接口编程、策略模式与配置文件组合实现的动态加载机制,核心在于解耦。文章通过具体示例介绍了SPI的使用方法,包括定义接口、创建配置文件及加载实现类的过程,并分析了其原理与优缺点。SPI适用于框架扩展或替换场景,如JDBC驱动加载、SLF4J日志实现等,但存在加载效率低和线程安全问题。
理解的Java中SPI机制
|
25天前
|
Java静态代码块深度剖析:机制、特性与最佳实践
在Java中,静态代码块(或称静态初始化块)是指类中定义的一个或多个`static { ... }`结构。其主要功能在于初始化类级别的数据,例如静态变量的初始化或执行仅需运行一次的初始化逻辑。
39 4
Java线程池ExecutorService学习和使用
通过学习和使用Java中的 `ExecutorService`,可以显著提升并发编程的效率和代码的可维护性。合理配置线程池参数,结合实际应用场景,可以实现高效、可靠的并发处理。希望本文提供的示例和思路能够帮助开发者深入理解并应用 `ExecutorService`,实现更高效的并发程序。
47 10
【潜意识Java】深度分析黑马项目《苍穹外卖》在Java学习中的重要性
《苍穹外卖》项目对Java学习至关重要。它涵盖了用户管理、商品查询、订单处理等模块,涉及Spring Boot、MyBatis、Redis等技术栈。
267 4
【潜意识Java】Java基础教程:从零开始的学习之旅
本文介绍了 Java 编程语言的基础知识,涵盖从简介、程序结构到面向对象编程的核心概念。首先,Java 是一种高级、跨平台的面向对象语言,支持“一次编写,到处运行”。接着,文章详细讲解了 Java 程序的基本结构,包括包声明、导入语句、类声明和 main 方法。随后,深入探讨了基础语法,如数据类型、变量、控制结构、方法和数组。此外,还介绍了面向对象编程的关键概念,例如类与对象、继承和多态。最后,针对常见的编程错误提供了调试技巧,并总结了学习 Java 的重要性和方法。适合初学者逐步掌握 Java 编程。
63 1
|
3月前
|
Java中的异常处理机制深度剖析####
本文深入探讨了Java语言中异常处理的重要性、核心机制及其在实际编程中的应用策略,旨在帮助开发者更有效地编写健壮的代码。通过实例分析,揭示了try-catch-finally结构的最佳实践,以及如何利用自定义异常提升程序的可读性和维护性。此外,还简要介绍了Java 7引入的多异常捕获特性,为读者提供了一个全面而实用的异常处理指南。 ####
114 20
Java 异常处理:机制、策略与最佳实践
Java异常处理是确保程序稳定运行的关键。本文介绍Java异常处理的机制,包括异常类层次结构、try-catch-finally语句的使用,并探讨常见策略及最佳实践,帮助开发者有效管理错误和异常情况。
240 6
Java 反射机制:动态编程的强大利器
Java反射机制允许程序在运行时检查类、接口、字段和方法的信息,并能操作对象。它提供了一种动态编程的方式,使得代码更加灵活,能够适应未知的或变化的需求,是开发框架和库的重要工具。
102 5
Java中的异常处理机制:深入解析与最佳实践####
本文旨在为Java开发者提供一份关于异常处理机制的全面指南,从基础概念到高级技巧,涵盖try-catch结构、自定义异常、异常链分析以及最佳实践策略。不同于传统的摘要概述,本文将以一个实际项目案例为线索,逐步揭示如何高效地管理运行时错误,提升代码的健壮性和可维护性。通过对比常见误区与优化方案,读者将获得编写更加健壮Java应用程序的实用知识。 --- ####
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等