从零开始的Java学习(15)

Episode-15 反射:探索面向对象的力量

不知不觉间,这个系列已经出到第十五节了。

让我们从对象开始,从对象结束,为这个系列画上一个圆满的句号吧!

Java 是一种强大的面向对象编程语言,它提供了许多高级特性,其中之一就是反射(Reflection)。通过反射,我们可以在运行时获取和操作类的信息,包括类的方法、字段和构造函数等。这为我们提供了灵活性和动态性,使得我们能够在运行时动态地创建对象、调用方法和访问属性。本文将介绍 Java 反射的基础知识,帮助你了解并开始使用这一强大的特性。

本期学习相关的知识

  • Java 反射的概念
  • Java 使用反射的基本步骤
  • 使用反射的具体例子

什么是反射?

反射是指在运行时动态地获取和操作类的信息。传统的编程方式要求在编译时就确定类的结构和调用方式,而反射则允许我们在运行时动态地获取和修改这些信息。通过反射,我们可以检查类的方法、字段和构造函数等,并且可以动态地创建对象、调用方法和访问属性。

Java 反射的核心类主要集中在 java.lang.reflect 包中。以下是几个重要的类和接口:

  • Class:表示类的实例,可以获取类的方法、字段和构造函数等信息。
  • Constructor:表示类的构造函数,可以用于创建对象。
  • Method:表示类的方法,可以用于调用方法。
  • Field:表示类的字段,可以用于访问和修改属性值。

Java 使用反射的基本步骤

一般来说,使用Java的反射需要经过下列步骤:

  1. 获取类的 Class 对象:
    可以通过类的全限定名或者对象的 getClass() 方法获取类的 Class 对象。
   Class<?> clazz = MyClass.class; // 通过类名获取
   Class<?> clazz = myObject.getClass(); // 通过对象获取
  1. 获取类的构造函数:
    通过 Class 对象的 getConstructor()getDeclaredConstructor() 方法可以获取类的构造函数。
   Constructor<?> constructor = clazz.getConstructor(paramTypes); // 公共构造函数
   Constructor<?> constructor = clazz.getDeclaredConstructor(paramTypes); // 所有构造函数
  1. 创建对象:
    使用构造函数的 newInstance() 方法可以创建对象。
   Object object = constructor.newInstance(args);
  1. 获取类的方法:
    通过 Class 对象的 getMethod()getDeclaredMethod() 方法可以获取类的方法。
   Method method = clazz.getMethod("methodName", paramTypes); // 公共方法
   Method method = clazz.getDeclaredMethod("methodName", paramTypes); // 所有方法
  1. 调用方法:
    使用方法的 invoke() 方法可以调用方法。
   Object result = method.invoke(object, args);
  1. 获取类的字段:
    通过 Class 对象的 getField()getDeclaredField() 方法可以获取类的字段。
   Field field = clazz.getField("fieldName"); // 公共字段
   Field field = clazz.getDeclaredField("fieldName"); // 所有字段
  1. 访问字段:
    可以使用字段的 get()set() 方法来读取和修改字段的值。
   Object value = field.get(object); // 读取字段的值
   field.set(object, newValue); // 修改字段的值

通过以上步骤,我们可以在运行时获取类的信息,并且动态地创建对象、调用方法和访问属性。

使用反射的具体例子

现在,让我们按照上述的步骤使用一次Java的反射吧!

让我们先创建一个类,这个类将作为我们反射的对象:

package ReflectionTest;

public class MyClass {
    private String name = "undefined";

    public MyClass() {
    }

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

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

    public void sayHowAreYou() {
        System.out.println("How are you, Reflection?");
    }
    
    @Override
    public String toString() {
        return "MyClass{" +
                "name='" + name + '\'' +
                '}';
    }
}

假如我们一开始不知道上面的这个类有什么构造方法,我们可以用下面这个程序来检测:

import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Constructor;

import ReflectionTest.MyClass;

public class ReflectionExample {
    public static void main(String[] args) throws Exception {
        Class<MyClass> clazz = MyClass.class;
        Object object = clazz.newInstance(); // 创建对象

        Constructor<?>[] constructors = clazz.getDeclaredConstructors(); // 获取所有构造方法
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
    }
}

编译运行上述代码,我们会得到如下结果:

反射_获取构造方法

接下来,让我们通过反射来使用一下这个类的构造方法和成员方法。

import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Constructor;

import ReflectionTest.MyClass;

public class ReflectionExample {
    public static void main(String[] args) throws Exception {
        Class<MyClass> clazz = MyClass.class;

        // 使用无参构造方法创建对象
        Constructor<?> constructor = clazz.getDeclaredConstructor();
        Object object = constructor.newInstance();
        System.out.println(object); // 输出对象信息

        // 使用带参构造方法创建对象
        Constructor<?> paramConstructor = clazz.getDeclaredConstructor(String.class);
        Object paramObject = paramConstructor.newInstance("John");
        System.out.println(paramObject); // 输出对象信息

        // 调用对象的方法
        Method method = clazz.getMethod("sayHello");
        method.invoke(object);
        method.invoke(paramObject);
        
        Method method1 = clazz.getMethod("sayHowAreYou");
        method1.invoke(object);
        method1.invoke(paramObject);
    }
}

编译运行得如下结果,可以看出来通过反射可以使用到MyClass类的构造方法和成员方法,而不是常规地new一个对象。

反射_使用构造方法和成员方法

总结

Java中的反射是一项强大的特性,它允许我们在运行时动态地获取和操作类的信息。通过反射,我们可以灵活地创建对象、调用方法和访问属性,从而实现更高度的动态性和灵活性。然而,要谨慎使用反射,因为它可能会带来一些性能开销和安全风险,但在某些情况下,它是一种非常有用的工具。

希望本文能够帮助你入门 Java 反射,并在实际开发中发挥它的威力。

谢谢观看!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值