首页 > 编程语言 >Java动态性

Java动态性

时间:2022-09-02 22:01:24浏览次数:57  
标签:Class Java clazz 获取 动态性 class 加载

Java动态性

动态语言

程序运行时可以改变程序结构或变量类型。典型动态语言:Python、ruby、javascript等

C/C++、Java不是动态语言,但Java可称为“准动态语言”,它有一定动态性,Java的动态性让编程更加灵活。

反射机制

  • 指的是可以于运行时加载、探知、使用编译期间完全未知的类。
  • 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;
    Class c = Class.forName("com.bjsxt.test.User");
  • 加载完类之后,在堆内存中,就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。

Class类

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

  • Class类的对象包含了某个被加载类的结构。一个被加载的类对应一个Class对象。

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

  • Class类是Reflection的根源。针对任何您想动态加载、运行的类,唯有先获得相应的Class对象

Class类获取

Class clazz = 对象引用.getClass();
Class clazz = 类名.class;
Class clazz = Class.forName("包名.类名");

一个类被加载后,JVM会加载一个对应该类的Class对象,类的整个结构信息会放到该Class对象中。一个类只对应一个反射对象,加载多次也只是那一个。

Class类成员获取

  • 获取成员变量

    import java.lang.reflect.Field;//获取成员变量需导入该包
    
    Field[] fileds = clazz.getFields();//该方法只能获取public属性
    Field[] fileds = clazz.getDeclareFields();//该方法能获取所有属性
    Field[] filed = clazz.getDeclareField("属性名");//该方法能获取指定属性
    
  • 获取类方法

    import java.lang.reflect.Method;//获取类方法需导入该包
    
    Method methods = clazz.getMethods();//该方法只能获取public类方法
    Method methods = clazz.getDeclareMethods();//该方法能获取所有类方法
    Method method = clazz.getDeclareMethod("方法名", 参数类型.class);//该方法能获取指定类方法
    
  • 获取构造器

    import java.lang.reflect.Constructor;//获取构造器需导入该包
    
    Constructor constructors = clazz.getMethods();//该方法只能获取public构造器
    Constructor constructors = clazz.getDeclareMethods();//该方法能获取所有构造器
    Constructor constructor = clazz.getDeclareMethod(参数类型.class);//该方法能获取指定构造器
    

动态操作

  • 动态实例化类对象

    Class<Test> clazz = (Class<Test>)Class.forName("kiang.test.Test");//如果在此处不写泛型,则下面每次实例化都需要强制类型转换
    Test t = clazz.newInstance();//实际上是调用了类的无参构造器(此方法已弃用)
    Test t = clazz.getDeclaredConstructor(int.class, int.class, String.class).newInstance(1,2,"kiang");//现在一般这么用
    
    • 这里有个傻逼问题,至今无解
  • 动态调用普通方法

    Test t = clazz.getDeclaredConstructor(int.class, int.class, String.class).newInstance(1,2,"kiang");
    Method m = clazz.getDeclaredMethod("setName", String.class);
    m.invoke(t, "fuck");
    
  • 动态操作属性

    Test t = clazz.getDeclaredConstructor(int.class, int.class, String.class).newInstance(1,2,"kiang");
    Field field = clazz.getDeclaredField("name");
    field.setAccessible(true);//禁止执行访问安全检查
    field.set(t, "fuck");
    
    • 反射调用会比普通调用更加耗时,禁止执行访问安全检查可以提速几倍,但仍比不上普通调用。

动态编译

Java 6.0引入了动态编译机制。

动态编译的应用场景:

  • 可以做一个浏览端编写Java代码,上传服务器编译和运行的在线测评系统。
  • 服务器动态加载某些类文件。

动态编译的两种做法:

  • 通过Runtime调用javac,启动新的进程去操作。
  • 通过JavaCompiler动态编译。

通过JavaCompiler动态编译

public static int compileFiles(String sourceFile){
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    int result = compiler.run(null, null, null, sourceFile);
    System.out.println(result == 0 ? "编译成功" : "编译失败");
    return result;
}

run方法的四个参数:

  1. 为Java编译器提供参数
  2. 得到Java编译器的输出信息
  3. 接收编译器的错误信息
  4. 可变参数能传入一个或多个(使用String数组)Java源文件
  5. 返回值:0表示编译成功,非0表示编译失败。

标签:Class,Java,clazz,获取,动态性,class,加载
From: https://www.cnblogs.com/AncilunKiang/p/16651494.html

相关文章

  • 2022.9.2-2022年王建民JAVA课前测试
    石家庄铁道大学2022年秋季  2021级课堂测试试卷(一)(15分)课程名称:JAVA语言程序设计 任课教师:王建民       考试时间:150分钟  一、考试要求:1、按照测......
  • 2022年java第一次随堂测试
    //源代码importjava.util.Scanner;publicclassRoomManagement{ publicstaticvoidmain(String[]args){ Scannersc=newScanner(System.in); RoomInformati......
  • Java中this和super的用法总结
    原文:https://www.cnblogs.com/hasse/p/5023392.htmlthis指向对象本身的指针,形参与成员名字重名,用this来区分。super超(父)类对象的一个指针。一、thisthis是自身......
  • Java 并发编程解析 | 如何正确理解Java领域中的锁机制,我们一般需要掌握哪些理论知识?
    苍穹之边,浩瀚之挚,眰恦之美;悟心悟性,善始善终,惟善惟道!——朝槿《朝槿兮年说》写在开头提起Java领域中的锁,是否有种“道不尽红尘奢恋,诉不完人间恩怨“的”感同身受“......
  • Android学习笔记八(JAVA):数据库与Room持久性库,菜单栏,数据绑定
    本篇笔记实现如下所示的功能。在NoteListFragment页面增加了菜单栏,菜单栏中有NewNote选项,点击它跳转到新建Note页面。输入TITLE和CONTENT后,点击CREATE按钮,会在数据库中添......
  • Intellij IDEA 'Error:java: 无效的源发行版:13'
      原文链接:https://blog.csdn.net/liuqiker/article/details/101528205  1,首先亮一下我的IDEA版本:2,我遇上的问题:3,我怎么解决的?1,首先亮一下我的IDEA版本(官网下载......
  • java 内存模型之 volatile 核心原理与应用
    1.happens-before规则https://blog.csdn.net/qq_39935047/article/details/1203847992.Juc12_Volatile的可见性、不保证可见性、有序性、使用、内存屏障四大指令StoreSt......
  • 使用JavaConfig实现配置
    @Configuration在一个类上加了@Configration之后就类似<beans><beanid="xxx" class="xxxxxx"/></beans>这个也会被Spring容器托管,注册到容器中,因为他本来就是一个@......
  • java学习笔记018 反射
    1.java.lang.Class获取Class对象的四种方式//1Classclazz1=Person.class;//2Personp=newPerson();Classclazz2=p.getClass();//3 用得多Classclazz3=......
  • java.lang.reflect.InvocationTargetException
    1.自定义BaseServlet时候,里面的方法应该是重新HttpServlet里的service方法,自己写成dogetdopost了,错误!2.mapper的xml配置文件,查询总数的方法selectTotalCount需要......