什么是反射?

yizhihongxing

反射

反射是在运行时动态地发现和使用类的信息的机制。Java 反射机制提供了程序在运行时拥有访问并操作任何一个对象、变量、方法的能力。

Java 反射最初被设计出来是为了支持类浏览器这样的工具。在此基础上,JavaBean等技术也得以广泛应用。

反射的使用

在Java中,使用反射需要经过如下基本步骤:
1. 获取需要使用的类的Class对象;
2. 根据Class对象获取构造方法、属性、方法等信息;
3. 使用获取到的构造方法、属性、方法等信息进行实例化、访问、操作等。

获取Class对象

在Java中,要获取某个对象的Class对象,可以使用Java反射提供的“类.class”语法或者“实例.getClass()”语法。示例如下:

Class clazz1 = String.class;
Class clazz2 = "hello".getClass();

System.out.println(clazz1);
System.out.println(clazz2);

输出结果:

class java.lang.String
class java.lang.String

获取构造方法

在Java中,可以使用反射获取指定类的构造方法。示例如下:

Class<?> clazz = String.class;
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors) {
    System.out.println(constructor);
}

输出结果:

public java.lang.String(byte[],java.nio.charset.Charset)
public java.lang.String(byte[],int,int,java.nio.charset.Charset)
public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int,int)
public java.lang.String(byte[])
public java.lang.String(java.lang.StringBuilder)
public java.lang.String(byte[],int,int,int)
public java.lang.String(int[],int,int)
public java.lang.String(byte[],int,int,java.nio.charset.CharsetEncoder)
public java.lang.String(char[],int,int)
public java.lang.String(byte[],int,int,java.lang.String,int[])
public java.lang.String()
public java.lang.String(int[],int,int,int)
public java.lang.String(java.lang.String,java.lang.String,java.lang.String)
public java.lang.String(java.lang.String)
public java.lang.String(java.lang.StringBuffer)
public java.lang.String(char[])
public java.lang.String(int[],int,int,int,int[])
public java.lang.String(java.lang.String,int)

获取属性

在Java中,可以使用反射获取指定类的属性。示例如下:

Class<?> clazz = String.class;
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
    System.out.println(field);
}

输出结果:

private final char[] value
private final int offset
private final int count
public static final java.util.Comparator<java.lang.Object> CASE_INSENSITIVE_ORDER
public static final java.lang.String EMPTY
public static final char[] CA

获取方法

在Java中,可以使用反射获取指定类的方法。示例如下:

Class<?> clazz = String.class;
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
    System.out.println(method);
}

输出结果:

public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public int java.lang.String.compareTo(java.lang.Object)
public int java.lang.String.compareTo(java.lang.String)
public boolean java.lang.String.equals(java.lang.Object)
public java.lang.String java.lang.String.toString()
public native int java.lang.String.hashCode()
public int java.lang.String.length()
public int java.lang.String.indexOf(int)
public int java.lang.String.indexOf(java.lang.String)
public int java.lang.String.indexOf(int,int)
public java.lang.String java.lang.String.substring(int)
public java.lang.String java.lang.String.substring(int,int)
public char[] java.lang.String.toCharArray()
public byte[] java.lang.String.getBytes(java.nio.charset.Charset)
public byte[] java.lang.String.getBytes()
public boolean java.lang.String.endsWith(java.lang.String)
public boolean java.lang.String.equalsIgnoreCase(java.lang.String)
public int java.lang.String.indexOf(java.lang.String,int)
public boolean java.lang.String.isEmpty()
public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String)
public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String)
public java.lang.String java.lang.String.trim()
public boolean java.lang.String.contains(java.lang.CharSequence)
public int java.lang.String.lastIndexOf(int)
public int java.lang.String.lastIndexOf(java.lang.String)
public int java.lang.String.lastIndexOf(int,int)
public java.lang.String java.lang.String.toLowerCase()
public java.lang.String java.lang.String.toUpperCase()
public boolean java.lang.String.matches(java.lang.String)
public java.lang.String[] java.lang.String.split(java.lang.String,int)
public java.lang.String[] java.lang.String.split(java.lang.String)
public java.lang.String java.lang.String.valueOf(java.lang.Object)
public java.lang.String java.lang.String.valueOf(int)
public java.lang.String java.lang.String.valueOf(char[])
public java.lang.String java.lang.String.subSequence(int,int)
public java.util.Locale java.lang.String.getLocale()
public java.lang.String java.lang.String.intern()

示例

示例1:通过反射创建对象并调用方法

public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public void sayHello() {
        System.out.println("Hello, " + name + "!");
    }
}

public class Test {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 获取User类的Class对象
        Class<?> userClass = User.class;

        // 获取User类的构造方法
        Constructor<?> constructor = userClass.getConstructor(String.class);

        // 调用构造方法创建对象
        User user = (User) constructor.newInstance("Tom");

        // 获取User类的sayHello方法
        Method sayHelloMethod = userClass.getDeclaredMethod("sayHello");

        // 调用sayHello方法
        sayHelloMethod.invoke(user);
    }
}

输出结果:

Hello, Tom!

示例2:通过反射修改私有属性

public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public void sayHello() {
        System.out.println("Hello, " + name + "!");
    }
}

public class Test {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        // 创建User对象
        User user = new User("Tom");

        // 获取User类的Class对象
        Class<?> userClass = User.class;

        // 获取User类的name属性
        Field nameField = userClass.getDeclaredField("name");

        // 设置name属性可访问
        nameField.setAccessible(true);

        // 修改name属性的值
        nameField.set(user, "Jerry");

        // 调用sayHello方法
        user.sayHello();
    }
}

输出结果:

Hello, Jerry!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:什么是反射? - Python技术站

(0)
上一篇 2023年5月10日
下一篇 2023年5月10日

相关文章

  • Java各种排序算法汇总(冒泡,选择,归并,希尔及堆排序等)

    Java各种排序算法汇总 本文将详细讲解Java中常见的各种排序算法,包括冒泡排序、选择排序、归并排序、希尔排序、堆排序等,以及他们的实现代码和时间复杂度分析。 冒泡排序 冒泡排序是一种基础的排序算法,核心思想是将相邻的元素两两比较,将较大的元素向后移动。代码如下: public static void bubbleSort(int[] array) { f…

    Java 2023年5月19日
    00
  • js实现窗口全屏示例详解

    首先,实现网页全屏有两种方式:一种是使用原生JavaScript,另一种是使用第三方库。 使用原生JavaScript实现窗口全屏 function fullscreen() { var elem = document.documentElement; if (elem.requestFullscreen) { elem.requestFullscreen(…

    Java 2023年5月23日
    00
  • SpringMVC文件上传原理及实现过程解析

    SpringMVC文件上传原理解析 在SpringMVC文件上传时,客户端向服务器发送文件,SpringMVC通过MultipartResolver对请求进行处理,解析出其中的文件,并将文件保存到指定的位置。MultipartResolver是一个接口,SpringMVC提供了两种实现方式: StandardServletMultipartResolver:…

    Java 2023年6月16日
    00
  • tomcat内存溢出问题解决经历

    下面我将为你详细讲解“Tomcat内存溢出问题解决经历”的完整攻略。 问题描述 Tomcat在运行过程中会经常出现内存溢出的问题,这会导致服务器的不稳定和运行效率的降低。我们需要针对这个问题进行解决,以下是具体的解决经历。 解决方法 方法一:增加JVM内存限制 如果Tomcat遇到内存溢出的问题,我们可以通过增加JVM内存限制的方式来解决。具体的做法是在To…

    Java 2023年6月15日
    00
  • XML经典问答

    XML经典问答攻略 本文将为您提供针对XML经典问题的攻略,以解决常见的XML相关问题。以下是您需要注意的几个方面: 1. XML文档结构 XML文件通常由一个根元素(root element)组成,并由开始标签和结束标签加以表示。中间可以嵌套若干子元素。元素可以包含属性(attribute)或文本(text)。如下所示: <?xml version=…

    Java 2023年5月20日
    00
  • SpringMVC静态资源配置过程详解

    简介 在SpringMVC应用程序中,静态资源是指不需要动态生成的文件,例如CSS、JavaScript、图片等。在本文中,我们将介绍如何在SpringMVC应用程序中配置静态资源,并提供两个示例说明。 静态资源配置 在SpringMVC应用程序中,我们可以通过以下两种方式来配置静态资源: 使用<mvc:resources>元素配置静态资源。 使…

    Java 2023年5月17日
    00
  • J2ME/J2EE实现用户登录交互 实现代码

    J2ME和J2EE都是Java程序开发的重要领域,其中J2EE是面向企业级应用开发的,而J2ME则是面向移动设备的小型Java平台。在开发应用程序时,用户登录交互是不可或缺的一个功能,本文将讲解如何使用J2ME和J2EE实现用户登录交互,并提供两个示例。 J2ME实现用户登录交互 J2ME的用户界面开发常用的框架是MIDP(Mobile Informatio…

    Java 2023年6月15日
    00
  • 一篇文章搞定数据库连接池

    数据库连接池是在应用程序和数据库之间起着缓冲作用的一个数据结构,其可以存储多个已经连接到数据库的连接,进行数据库操作时从连接池获取连接,使用完后再将连接返回连接池,避免了重复创建和断开数据库连接,既提高了数据库操作的性能,也节约了资源。 一、数据库连接池的基本介绍 数据库连接池是应用程序和数据库之间的中间件,其分为多个阶段: 应用程序向连接池请求连接。 连接…

    Java 2023年6月16日
    00
合作推广
合作推广
分享本页
返回顶部