首页 > 编程语言 >java基础篇之反射(简单详细,快速入门)

java基础篇之反射(简单详细,快速入门)

时间:2024-09-24 19:22:59浏览次数:9  
标签:反射 java 入门 aClass Class Student class name

@[TOC]希望本文能帮助你增加对反射的理解

反射的简单叙述及相关性质

反射的源头 —— Class类

反射的主要应用

反射的简单叙述及相关性质

  1. 能够分析类能力的程序为反射,反射机制的功能极其强大,下面我们就来简单举个例子
public class Student {
    private String name;
    private int age;
    private int id;
    
    private Student(){
    	name = "";
    	age = 0;
    	id = 0;
    }
	
	private void showInfo(){
		System.in.println("Hello world");	
	}
}

出了Student类,由于封装性的缘故,我们就不能直接调用那些私有的结构(属性、方法、构造器),但使用了反射,我们就可以调用运行时类的任意结构。*可能有的人会认为反射与封装性相矛盾,但实际上并不这样,封装性中private表示的是并不建议你调用该属性,但反射主要是表现能不能调用,所以二者并不矛盾。*其次,反射主要是开发工具的程序员对他感兴趣(比如框架的底层实现机制就有反射,学习反射有助于你对框架底层原码的理解),一般的程序员不怎么会用到反射。

反射的源头 – Class类

1.Class类的理解

当我们对java文件进行编译时,会生成一个或多个.class字节码文件,接着我们试着去运行java程序,会将.class文件加载到内存中,每个.class的结构就对应着一个Class类的实例
那么,Clas类又可以指向哪些java文件呢?
(1)primitive type:基本数据类型
(2)interface:接口
(3)[]:数组
(4)enum:枚举
(5)annotation:注解
(6)class:外部类、内部类
(7)void
也就是说,java中的所有类型!

2.获取Class类的实例的主要的几种方式

① 类名.class

Class aClass = Student.class;

② 运行时类对象的getClass()方法

Student std = new Student();
Class aClass = std.getClass();

③ Class类的静态方法forName(“className”)

String className = "java.util.Random";//此处传入的参数是类的全类名,这样才能具体的知道你需要的是哪个类
Class aClass = Class.forName(className);

尽管看上去第一种方式是最方便、最快捷的,但是方法三是不是更能体现反射的动态性呢?通过传入不同的全类名来获取Class类的实例,然后再进行后续操作。

  • 注意 :Class类的getName()方法应用在数组类型会返回一些奇怪的东西
Class aClass = int[].class;
System.out.println(aClass.getName());

会显示"[I;"
*

反射的主要应用

在介绍反射的主要应用前,我先给大家看看我用反射所调用的Student类的结构,且为了代码等简单一些,我在其中遇到的异常都先用throws抛出异常

public class Student {
    private int age;
    private String name;

    public Student() {
    }

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }
    
    private String showInfo(){
        return "name = " + name + ",age = " + age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

① 调用指定的构造器

   @Test
   public void test() throws Exception {
        Class aClass = Student.class;//获取类的实例

		//下面这步适用于获取类的指定构造器,像我这种传入的是String.class和int.class就对应着指定构造器的形参列表的参数类型
        Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class);
       //这步主要是为了设置构造器的权限,防止我们没有足够的权限调用构造器,有了这步,可以看到即使是private修饰的构造器我们也                可以调用,属性和方法也是如此,就不再过多赘述了
        declaredConstructor.setAccessible(true);
        //这步就是创建类对应的实例
        Student std = (Student) declaredConstructor.newInstance("Tony", 18);

        System.out.println(std);
   }

在讲述接下来的有关于反射的运用时,先来介绍一下在jdk9.0中被弃用的Class的newInstance()方法

 Class aClass = Student.class;
 Student std = (Student) aClass.newInstance();

使用上述的代码同样也可以创建Student类的一个实例,但是对Student类有一定的要求,必须有一个空参的构造器,且该构造器的访问权限还需要达到一定的条件,为了方便,我接下来都用此方法创建类的实例
② 调用指定的属性

    @Test
    public void test() throws Exception {
        Class aClass = Student.class;
        Student std = (Student) aClass.newInstance();

		//这步主要时找到Student类的名为name的属性
        Field nameField = aClass.getDeclaredField("name");
        nameField.setAccessible(true);
        
        //设置指定对象的name属性的值
        nameField.set(std,"jerry");
        //获取指定对象的name属性的值,返回值类型为Object
        System.out.println(nameField.get(std));
    }

③ 调用指定的方法

    @Test
    public void test7() throws Exception {
        Class aClass = Student.class;
        Student std = (Student) aClass.newInstance();
		
		//调用Student类中名为showInfo的方法,形参为String类
        Method showInfo = aClass.getDeclaredMethod("showInfo", String.class);
        showInfo.setAccessible(true);

		//invoke即为方法的调用,传入参数为所对应的对象和实参,返回值即为对应方法的返回值,如果返回值为void的话,则返回null
        String returnValue = (String) showInfo.invoke(std, "CHINA");
        System.out.println(returnValue);
    }
}

好了,以上就是关于反射的一些比较基础但比较主要的知识点,希望能对于你对反射的学习有所帮助

标签:反射,java,入门,aClass,Class,Student,class,name
From: https://blog.csdn.net/2301_80113755/article/details/142469577

相关文章

  • Java学习笔记(上)——动力节点老杜(某站2000万播放)
    此文章是本人大一学习java时记的笔记,原视频在https://www.bilibili.com/video/BV1Rx411876f,配套服用更佳!一.JAVA开发环境的搭建1.常用的Dos命令1.1win+r打开Dos命令窗口1.2什么是Dos命令在最初的计算机中没有图形界面,也就是说通过Dos命令窗口可以完全完成文件的新建、......
  • 《 C++ 修炼全景指南:十二 》用红黑树加速你的代码!C++ Set 和 Map 容器从入门到精通
    摘要本文详细介绍了基于红黑树实现的Set和Map容器,包括其底层设计原理、插入和删除操作的实现细节、性能分析与优化策略,以及实际应用场景和未来发展方向。通过采用红黑树的数据结构,Set和Map容器能够高效地处理有序数据,保持O(logn)的时间复杂度,适用于各种数据存储......
  • JavaEE——多线程
    接着上篇博客我们已经学习了进程的相关概念,了解到进程里面的相关重要属性,那么这篇博客呢我们要学习一个新的知识点——线程!一、引入进程的目的首先引入进程这个概念,是为了解决“并发编程”这样的问题。因为CPU再往小了做,比较困难了,这是因为CPU进入了多核心的时代,要想进一......
  • JavaEE——多线程Thread 类及常见方法
    目录 一、Thread(Stringname)二、是否后台线程isDeamon()三、是否存活isAlive()四、run()方法和start()方法的区别五、中断线程法一:法二:六、线程等待join()七、线程休眠sleep()一、Thread(Stringname)定义:这个东西是给线程(thread对象)起一个名字。起一个......
  • Java:排序算法
    Java中有很多种排序算法,每种算法都有其特点,适用于不同的场景。下面列举一些常见的排序算法,并简要介绍其特点:冒泡排序(BubbleSort)原理:通过重复遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复进行的,直到没有再需要交换的元素,这意......
  • Java BeanUtils使用介绍
    ‌JavaBeanUtils是一个广泛使用的Java工具类,提供了一系列方法来简化JavaBean对象之间的属性复制和操作。‌使用JavaBeanUtils可以方便地实现对象之间的属性复制、属性设置和获取、类型转换等功能。以下是使用JavaBeanUtils的基本步骤和注意事项:1.添加依赖‌:首先,你需要在项目......
  • java解析xml
    参考资料水平有限,欢迎交流千问ai阿伟的反射知识学习泛型知识学习软件设计模式(java版)程细柱目标xml<?xmlversion="1.0"encoding="UTF-8"?><conf><farm>SGFarm</farm><student><name>李四</name>&......
  • Java反射
    一、如何获取一个类:1、Classcls=Class.forName("java.lang.String");2、Stringstr="zhangsan";Classcls=str.getClass();3、Classcls=String.class;//注意String.class的class是小写的C二、利用反射访问类中的字段:1、getFields()方法:获得某个类中所有......
  • 基于Node.js+vue基于java的学生宿舍管理系统(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着高等教育规模的不断扩大,学生宿舍作为校园生活的重要组成部分,其管理效率与服务质量直接关系到学生的日常生活体验及学校的整体管理水平。传统的学生宿舍......
  • Java多线程
    文章目录前言1实现多线程1.1多线程概述1.2多线程的实现方式1.3线程休眠1.4线程优先级1.5守护线程2线程同步2.1同步代码块2.2Lock锁2.3死锁3生产者消费者3.1生产者和消费者模式概述3.2阻塞队列基本使用3.3阻塞队列实现等待唤醒机制前言"劝君莫惜金......