java 动态性之反射机制 详解 案例(1)

简介: java 动态性之反射机制 详解 案例

1、反射机制

2、动态编译

3、动态执行javassript代码

4、动态字节码操作

动态语言


程序运行时,可以改变程序结构或变量类型。典型的语言:


1):Python、ruby、javascript等。


2):如下javascript代码:


funtion test(){
    var s ="var a=3;var b=5;alert(a+b);";
    eval(s);
  }

3):C,C++,JAVA不是动态语言,JAVA可以称之为“准动态语言”。但是JAVA有一定的动态性,我们可以利用反射机制、字节码操作获得类似动态语言的特性

4):JAVA的动态性让编程更加灵活!




1、反射机制


1):指的是可以于运行时加载、探知、使用编译期间完全未知的类。


2):程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性


<strong><span style="font-size:18px;">Class c = Class.forName("com.lyy.test.User");</span></strong>

 3):加载完类之后,在堆内存中,就产生了一个Class类型的对象(一个类只有一个Class对象)这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的机构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。

1.1 Class类介绍


java.lang.Class类十分特殊,用来表示Java中类型(class/interface/enum/annotation/primitive type/void)本身


1.1.1):Class类的对象包含了某个被加载类的机构,一个被加载的类对应一个Class对象


1.1.2):当一个class被加载,或当加载器(class loader)的definaClass()被JVM调用,JVM便自动产生一个Class对象


1.1.3):Class类是Reflection的根源


针对任何你想动态加载、运行的类,唯有先获得相应的Class对象




1.2 反射机制的常见作用


1.2.1):动态加载类、动态获取类的信息(属性、方法、构造器)


1.2.2):动态构造对象


1.2.3):动态调用类和对象的任意方法、构造器


1.2.4):动态调用和处理属性


1.2.5):获取泛型信息


1.2.6):处理注解



1.3 Class类的对象如何获取?


1.3.1):运用 getClass()


1.3.2):运用Class.forName()(最常被使用)


1.3.3):运用 .class语法





测试各种类型(class、interface、enum、annotaion,primitive type void void) 测试java.lang.Class对应的获取方式

package com.lyy.test;
/**
 * 测试各种类型(class、interface、enum、annotaion,primitive type void void) 测试java.lang.Class对应的获取方式
 * @author lyy
 *
 */
@SuppressWarnings("all")
public class Demo1 {
  public static void main(String[] args) {
    try {
      String path = "com.lyy.test.bean.User";
      Class<?> cls = Class.forName(path);
      //对象用来表示或封装一些数据 一个类加载后,JVM会创建一个对应该类的class对象,类的机构信息会放到对应的class对象中
      //class对象就像一面镜子一样,通过这面镜子可以看到对应的全部信息
      Class<?> clss = Class.forName(path);
      System.out.println(cls.hashCode());//一个类只对应一个Class对象
      System.out.println(clss.hashCode());
      Class strcls = String.class;
      Class strclass = path.getClass();
      System.out.println(strcls.equals(strclass));
      Class incls = int.class;
      int[] arr1 = new int[10];
      int[][] arr2 = new int[30][3];
      int[] arr3 = new int[30];
      double[] arr4 = new double[10];
      System.out.println(arr1.getClass().hashCode());
      System.out.println(arr2.getClass().hashCode());
      System.out.println(arr3.getClass().hashCode());
      System.out.println(arr4.getClass().hashCode());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
package com.lyy.test.bean;
public class User {
    private int id;
    private int age;
    private String uname;
    public int getId() {
      return id;
    }
    public void setId(int id) {
      this.id = id;
    }
    public int getAge() {
      return age;
    }
    public void setAge(int age) {
      this.age = age;
    }
    public String getUname() {
      return uname;
    }
    public void setUname(String uname) {
      this.uname = uname;
    }
    public void setUname() {
      this.uname = "lyy";
    }
    public User(int id, int age, String uname) {
      super();
      this.id = id;
      this.age = age;
      this.uname = uname;
    }
    //javabean必须要有无参构造方法
    public User() {
      super();
    }
}

应用反射API,获取类的信息(类的名字、属性、方法、构造器等)

package com.lyy.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
 * 应用反射API,获取类的信息(类的名字、属性、方法、构造器等)
 * @author lyy
 *
 */
public class Demo2 {
  public static void main(String[] args) {
    String path = "com.lyy.test.bean.User";
    try {
      Class<?> cls = Class.forName(path);
      //获取类的名字
      System.out.println(cls.getName());//获得包名+类名
      System.out.println(cls.getSimpleName());// 类名 User
      //获取属性信息
//      Field[] field = cls.getFields(); //只能获取public下的field
      Field[] field = cls.getDeclaredFields();//获取所有的field
      Field f = cls.getDeclaredField("uname");
      System.out.println(field.length);
      for (Field temp : field) {
        System.out.println("属性:"+temp);
      }
      //获取方法信息
      Method[] method = cls.getDeclaredMethods();
      Method method1= cls.getDeclaredMethod("getUname",null);
      //如果方法有参数,则必须传递参数类型对应的Class对象
      Method method2= cls.getDeclaredMethod("setUname",String.class);
      for(Method m:method){
        System.out.println("方法:"+m);
      }
      //获取构造信息
      Constructor[] con = cls.getDeclaredConstructors();
      Constructor c =cls.getDeclaredConstructor(int.class,int.class,String.class);
      System.out.println("获取构造器:"+c);
      for(Constructor m:con){
        System.out.println("构造器:"+m);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

image.png

通过反射动态的操作 构造器、方法、属性

package com.lyy.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.lyy.test.bean.User;
/**
 * 通过反射动态的操作 构造器、方法、属性
 * @author lyy
 *
 */
@SuppressWarnings("all")
public class Demo3 {
  public static void main(String[] args) {
    String path = "com.lyy.test.bean.User";
    try {
      Class<User> cls = (Class<User>) Class.forName(path);
      //通过反射API动态调用构造方法,构造对象
      User u = cls.newInstance();  //其实是调用了User的无参构造方法
      System.out.println(u);
      Constructor<User> c = cls.getDeclaredConstructor(int.class,int.class,String.class);
      User u1 = c.newInstance(1001,18,"lyy666");
      System.out.println(u1.getUname());
      //通过反射API 调用普通方法
      User u2 = cls.newInstance();
      Method method = cls.getDeclaredMethod("setUname",String.class);
      method.invoke(u2, "lyy而");//u2.setUname("lyy3");
      System.out.println(u2.getUname());
      //通过反射API操作属性
      User u4 = cls.newInstance();
      Field f = cls.getDeclaredField("uname");
      f.setAccessible(true);//这个属性不需要安全检查了,可以直接访问
      f.set(u4, "lyy4");//通过反射直接写属性
      System.out.println(u4.getUname());//通过反射直接读属性的值
      System.out.println(f.get(u4));
    } catch (Exception e) {
      e.printStackTrace();
    } 
  }
}

image.png

目录
相关文章
|
5天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
16 2
|
9天前
|
Java 编译器
探索Java中的异常处理机制
【10月更文挑战第35天】在Java的世界中,异常是程序运行过程中不可避免的一部分。本文将通过通俗易懂的语言和生动的比喻,带你了解Java中的异常处理机制,包括异常的类型、如何捕获和处理异常,以及如何在代码中有效地利用异常处理来提升程序的健壮性。让我们一起走进Java的异常世界,学习如何优雅地面对和解决问题吧!
|
20天前
|
XML 安全 Java
Java反射机制:解锁代码的无限可能
Java 反射(Reflection)是Java 的特征之一,它允许程序在运行时动态地访问和操作类的信息,包括类的属性、方法和构造函数。 反射机制能够使程序具备更大的灵活性和扩展性
33 5
Java反射机制:解锁代码的无限可能
|
8天前
|
Java 数据库连接 开发者
Java中的异常处理机制及其最佳实践####
在本文中,我们将探讨Java编程语言中的异常处理机制。通过深入分析try-catch语句、throws关键字以及自定义异常的创建与使用,我们旨在揭示如何有效地管理和响应程序运行中的错误和异常情况。此外,本文还将讨论一些最佳实践,以帮助开发者编写更加健壮和易于维护的代码。 ####
|
14天前
|
安全 IDE Java
Java反射Reflect机制详解
Java反射(Reflection)机制是Java语言的重要特性之一,允许程序在运行时动态地获取类的信息,并对类进行操作,如创建实例、调用方法、访问字段等。反射机制极大地提高了Java程序的灵活性和动态性,但也带来了性能和安全方面的挑战。本文将详细介绍Java反射机制的基本概念、常用操作、应用场景以及其优缺点。 ## 基本概念 ### 什么是反射 反射是一种在程序运行时动态获取类的信息,并对类进行操作的机制。通过反射,程序可以在运行时获得类的字段、方法、构造函数等信息,并可以动态调用方法、创建实例和访问字段。 ### 反射的核心类 Java反射机制主要由以下几个类和接口组成,这些类
33 2
|
16天前
|
jenkins Java 测试技术
如何使用 Jenkins 自动发布 Java 代码,通过一个电商公司后端服务的实际案例详细说明
本文介绍了如何使用 Jenkins 自动发布 Java 代码,通过一个电商公司后端服务的实际案例,详细说明了从 Jenkins 安装配置到自动构建、测试和部署的全流程。文中还提供了一个 Jenkinsfile 示例,并分享了实践经验,强调了版本控制、自动化测试等关键点的重要性。
48 3
|
18天前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
35 2
|
19天前
|
存储 缓存 安全
🌟Java零基础:深入解析Java序列化机制
【10月更文挑战第20天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
22 3
|
19天前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
13 2
|
19天前
|
安全 Java UED
深入理解Java中的异常处理机制
【10月更文挑战第25天】在编程世界中,错误和意外是不可避免的。Java作为一种广泛使用的编程语言,其异常处理机制是确保程序健壮性和可靠性的关键。本文通过浅显易懂的语言和实际示例,引导读者了解Java异常处理的基本概念、分类以及如何有效地使用try-catch-finally语句来处理异常情况。我们将从一个简单的例子开始,逐步深入到异常处理的最佳实践,旨在帮助初学者和有经验的开发者更好地掌握这一重要技能。
20 2