Java 反射之根基 Class 类

Java中反射机制很重要,Java的动态语言就是靠反射机制实现的,反射技术也是程序员走的更远必不可少的一个技能。一般情况下我们都是通过类来创建对象,如果要求通过一个对象找到一个类,就需要用到反射机制,各种开源框架的编写更是离不开反射的机制。

一、了解反射机制

一般我们写代码,按照如下的步骤使用一个类:

1、使用关键字 import 导入类所在的包;

2、使用类名称或者接口名称定义对象;

3、通过关键字 new 进行类对象实例化;

4、使用【对象.属性】进行类中属性的调用;

5、使用【对象.方法】进行类中方法的调用;

而 Java 中的反射过程就是指:在程序的运行过程中,把 Java 类中的各种元素映射成对应的类,并能动态的执行这些类的方法。

Java 反射机制里重要的几个类:

类:java.lang.Class

属性:java.lang.reflect.Field

构造方法:java.lang.reflect.Constructor

方法:java.lang.reflect.Method

用反射可以轻松的获取一个类中的以上元素,并可以动态地对其进行调用,在不知道别人写的代码的时候,可以通过配置来调用别人的代码,很多开源框架都离不开反射机制,反射的魅力也正如此。

二、认识 Class 类

1、了解 Object 类:

我们知道如果一个类没有明确的声明集成自哪个父类时,那么它默认继承 Object 类,Object 类是所有类的父类。

Object 类中的 getClass()方法的源码:

public final native Class<?> getClass();

getClass()方法返回的类型是一个 Class 类,Class 类就是 Java 反射的源头。以上的源码用到了 native 关键字和泛型,使用 native 关键字说明这个方法是原生函数,也就是这个方法是用 C/C++ 语言实现的,由 Java 通过 JNI 去调用的本地接口;如果不让程序出现警告信息,可以在使用时指定其操作的泛型具体类型,或者直接用“?”来取代。

2、获取 Class 类的 4 种实例化方式:

1、通过类本身的 class 属性实例化【类.class】;

2、通过 Object 类的 getClass()方法实例化【对象.getClass()】;

3、通过【Class.forName()方法】实例化,这种方式最常用,体现出了反射的动态性;

4、通过类的加载器获取;

```java /* * 如何获取Class类的实例的4种方式 / @Test public void TestClass() throws Exception { // 1、调用运行时类本身的.class属性 Class<?> clazz = User.class; System.out.println(clazz);

// 2、通过运行时类的对象获取
User p = new User();
Class<?> clazz1 = p.getClass();
System.out.println(clazz1);// 3、通过Class的静态方法获取,体现了反射的动态性,
// 传入className就能创建Class类的实例
String className = "com.jpm.reflection.User";
Class<?> clazz3 = Class.forName(className);
System.out.println(clazz3);// 4、通过类的加载器获取
ClassLoader classLoader = this.getClass().getClassLoader();
Class clazz4 = classLoader.loadClass(className);
System.out.println(clazz4);

}

/* * User类,用于演示反射,为了不影响体验,代码见文章末尾 / ```

运行结果:

class com.jpm.reflection.User
class com.jpm.reflection.User
class com.jpm.reflection.User
class com.jpm.reflection.User

三、类的加载器 ClassLoader

1、了解 Class 类的 3 种加载器:

1、系统类加载器(AppClassLoader):加载自定义类和普通 jar 包;

2、扩展类加载器(ExtClassLoader):加载 jre/lib/ext 目录下的类;

3、启动类加载器(BootStrapClassLoader):加载 jdk 的核心类库,启动类加载器 Java 代码获取不到;

/*** 类的加载器测试*/@Testpublic void testClassLoader() throws Exception {ClassLoader loader1 = this.getClass().getClassLoader();// 获取系统类加载器:sun.misc.Launcher$AppClassLoader@7852e922System.out.println(loader1);ClassLoader loader2 = loader1.getParent();// 获取系统类加载器的父类,扩展类加载器:sun.misc.Launcher$ExtClassLoader@330bedb4System.out.println(loader2);ClassLoader loader3 = loader2.getParent();// 获取扩展类的加载器的父类为null,说明引导类加载器无法在代码中获取System.out.println(loader3);Class clazz1 = User.class;ClassLoader loader4 = clazz1.getClassLoader();// 普通类用系统类加载器加载:sun.misc.Launcher$AppClassLoader@7852e922System.out.println(loader4);Class clazz2 = Class.forName("java.lang.String");ClassLoader loader5 = clazz2.getClassLoader();// String类是jdk的核心类库,用引导类加载器加载,返回null,说明类加载器无法在代码中获取System.out.println(loader5);}

运行结果:

sun.misc.Launcher$AppClassLoader@7852e922
sun.misc.Launcher$ExtClassLoader@330bedb4
null
sun.misc.Launcher$AppClassLoader@7852e922
null

2、类加载器的应用案例

1、获取 Java 包里的配置文件

@Testpublic void test() throws IOException {// 类加载器的应用,获取java包里的配置文件,但是不能获取工程目录下的文件ClassLoader loader = this.getClass().getClassLoader();InputStream is = loader.getResourceAsStream("configs//jdbc.properties");Properties properties = new Properties();properties.load(is);is.close();String user = properties.getProperty("user");System.out.println(user);String pwd = properties.getProperty("pwd");System.out.println(pwd);// 文件名不一定是properties后缀,也可以是txt等InputStream is1 = loader.getResourceAsStream("configs//jdbc.txt");Properties properties1 = new Properties();properties1.load(is1);is1.close();String user1 = properties1.getProperty("user");System.out.println(user1);String pwd1 = properties1.getProperty("pwd");System.out.println(pwd1);}

配置文件内容:

运行结果:

properties
jdbc.properties
txt
jdbc.txt

2、获取工程下的配置文件

上面的类加载器获取 java 包里的配置文件,但是不能获取工程目录下的文件,要想获取工程目录下的文件,可以使用如下的代码:

@Testpublic void test2() throws IOException {// 工程下的文件获取,文件名不一定是properties后缀,也可以是txt等InputStream is = new BufferedInputStream(new FileInputStream(new File("jdbc2.properties")));Properties pro = new Properties();pro.load(is);is.close();System.out.println(pro.getProperty("user"));System.out.println(pro.getProperty("pwd"));}

运行结果:

root
root123

四、Java 反射初体验

下面一个例子用来演示如何通过 Java 的反射机制,动态创建 User 类对象,并调用 User 类对象的属性赋值以及调用它的方法。

/*** 反射的初步体验*/@Testpublic void TestReflection() throws Exception {Class<?> clazz = Class.forName("com.jpm.reflection.User");// 创建运行时类User的对象Object user = clazz.newInstance();System.out.println(user);// 通过反射调用运行时类的指定public属性Field f1 = clazz.getField("name");f1.set(user, "JPM");System.out.println(user);// 通过反射调用运行时类的指定private属性Field f2 = clazz.getDeclaredField("age");f2.setAccessible(true); // 为私有属性赋值f2.set(user, 18);System.out.println(user);// 通过反射调用运行时类的指定方法Method m1 = clazz.getMethod("show");m1.invoke(user);Method m2 = clazz.getMethod("display", String.class);m2.invoke(user, "BJ");}/*** User类,用于演示反射*/
public class User {public String name;private int age;// 创建类时尽量写一个空参的构造器public User() {super();}public User(String name) {super();this.name = name;}public User(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User [name=" + name + ", age=" + age + "]";}public void show() {System.out.println("show method run!");}public void display(String address) {System.out.println("display method run,address=" + address);}
}

运行结果:

User [name=null, age=0]
User [name=JPM, age=0]
User [name=JPM, age=18]
show method run!
display method run,address=BJ

本文主要介绍了反射的概念、反射的源头 Class 类、类的 3 种加载器、类加载器ClassLoader 的应用场景、用Java 反射获取用户自定义类User,初步体验了 Java 反射机制的魅力。

后面我会用 2 篇文章来说明 Java 反射机制的深入体验,反射的高级应用动态代理的实现,敬请期待......

包里替换class文件_Java 反射之根基 Class 类相关推荐

  1. 提取原rpm包里的SPEC文件及重新打包

    一.概要 目的是要修改原rsyslog rpm包的systemd rsyslog.service文件,添加一行"ExecStartPre=/bin/bash -c "/usr/bi ...

  2. java 类.class_Java 反射之根基 Class 类

    Java 反射之根基 Class 类 Java中反射机制很重要,Java的动态语言就是靠反射机制实现的,反射技术也是程序员走的更远必不可少的一个技能.一般情况下我们都是通过类来创建对象,如果要求通过一 ...

  3. java反射class文件_Java反射(一)Class

    Java的反射应该算Java最灵活的一部分,反射机制是站在更高层次的抽象上,把Java中的类.方法.构造器.成员变量.接口等又抽象成了一个个类.先说说反射的基石Class类吧. Class类的实例表示 ...

  4. 在服务器里替换class文件,tomcat项目中class文件替换无效引发的思考

    最近在项目部署需要修改补丁文件时,我发现了一个特别古怪的问题: 替换掉原先的class文件无效,重启服务器也无效! 一般来说,我们更新网站,就是把更新后的文件,如jsp.class文件,替换掉原先的c ...

  5. java 反射类成员_java 反射(二)类成员

    在Java反射的包中定义一个接口java.lang.reflect.Member,它有三个实现类java.lang.reflect.Field, java.lang.reflect.Method, a ...

  6. javabean反射改字段内容_java反射机制给实体类相同字段自动赋值实例

    一.封装一个工具类 1.简易版 package net.aexit.construct.acceptance.websky.utils; import java.lang.reflect.Field; ...

  7. 怎么导出ij里面的java文件_Java應用系列:命令行生成jar包(附IJ Idea導出jar方法)...

    jar包 JAR(Java Archive,Java 歸檔文件)是與平台無關的壓縮文件,通常是用於將多個class文件組合成一個,.當創建jar包的時候,如果程序中有main入口函數,同時manife ...

  8. java.lang.class对象_Java反射——java.lang.Class 类简介

    Java的基本思想之一是万事万物即对象,类也是一种对象.但是类是什么对象呢?Java中的类是java.lang.Class的实例化对象,这被成为类类型. //java.lang.Class类中的的主要 ...

  9. java class 使用_Java反射机制(Class类的使用)

    1:通过无参构造实例化对象 package cn.itcast; /* * 通过无参构造实例化对象 * 通过Class类本身实例化对象,使用newInstance方法 * 需要注意的是:实例化类中存在 ...

最新文章

  1. Java 动态绑定 静态绑定
  2. redis常用命令getex_Redis常用命令(key、string、List)
  3. BufferedReader和FileReader的区别
  4. Linux bashrc和profile的用途和区别
  5. error: expected expression before ‘;’ token的问题
  6. 【报告分享】2021H1电商发展分析报告.pdf(附下载链接)
  7. 监控zabbix 服务并在异常时python 邮件报警
  8. cnBlog的windows live writer 客户端配置
  9. 企业微信2.6.0发布 可与微信用户群聊了
  10. Windows NT 5.1,Windows NT 6.0,Windows NT 6.1的概念
  11. SAP PP 空bom 清单及处理
  12. 使用vite插件编写tsx文件
  13. 做外贸找国外采购商的七个新方法
  14. 数据中心UPS不间断电源系统架构介绍
  15. 使用Visual Studio IDE编写程序时不显示窗口或窗口一闪而逝的解决方法
  16. 红米note4出厂系统版本_红米Note4发布!出厂就有MIUI8黑科技
  17. #730 (Div. 2) A 思维 C dfs D1 交互思维
  18. pandas.melt()使用介绍(宽表变长表)
  19. 《程序员修炼之道》读书笔记(二)--第三周
  20. 每天3.2亿人在刷抖音,而那些优秀的人却看这公众号的精华文章!

热门文章

  1. python中文名字-完美解决Python2操作中文名文件乱码的问题
  2. python装饰器-python修饰器(装饰器)以及wraps
  3. python处理流程-Python文件处理流程
  4. Camelot:从pdf中提取表格数据
  5. matlab溢出的标志inf,关于C#:溢出与信息
  6. 查找文本(grep)
  7. 最小生成树的两个性质:
  8. Pyhton学习——Day3
  9. 获取当前应用程序的文件名
  10. day 58 关于bootstrap