😊 @ 作者: 一恍过去
🎊 @ 社区: Java技术栈交流
🎉 @ 主题: Java开发基础系列(八):泛型及反射
⏱️ @ 创作时间: 2023年07月18日

在这里插入图片描述

目录

泛型

泛型是Java中的一个重要特性,是一种类型参数化的机制,它允许在类、接口、方法的定义和使用中指定类型参数,从而增加代码的通用性、类型安全性和可读性。它提供了在编译时期进行类型检查和类型安全的能力。通过使用泛型,可以编写更加通用和可复用的代码。

通过使用泛型,可以在定义类、接口和方法时使用类型参数,这些类型参数在使用时会被具体的类型替代。这样可以实现类、接口和方法的参数化,以适应不同类型的数据处理需求。

泛型的特点:

  • 类型安全:通过泛型,编译器可以在编译时检查类型,并提供类型安全的代码。这意味着可以在编译时捕获类型错误,避免在运行时出现类型转换错误。
  • 代码复用:泛型可以使代码更通用和可复用。通过定义泛型类、接口和方法,可以编写适用于多种类型的代码,而无需为每种类型都创建新的类或方法。
  • 可读性:使用泛型可以提高代码的可读性和可理解性。通过泛型的类型参数,可以明确指定方法或类与哪种类型相关联,从而提供更清晰的代码逻辑。

泛型的定义:

  • 泛型类:通过在类名后面使用尖括号(<>)和类型参数来定义泛型类。类型参数可以是单个字母或任意有效的标识符,表示可以在类的定义和使用中使用的类型。
    public class Test<T> {
        private T t;
    
        public void addItem(T t) {
            this.t= t;
        }
    
        public T getItem() {
            return t;
        }
    }
    
  • 泛型接口:与泛型类类似,可以在接口的名称后面使用尖括号(<>)和类型参数来定义泛型接口。
    public interface Test<T> {
        void add(T t);
    }
    
  • 泛型方法:在方法的返回类型前面使用尖括号(<>)和类型参数来定义泛型方法。
    public <T> void setArray(T[] array) {
        for (T t: array) {
            System.out.println(t);
        }
    }
    

反射

反射是Java的一项强大的特性,允许在运行时动态地获取和操作类的信息,包括类的方法、字段、构造函数等。通过反射,可以在编译时无法确定的情况下,通过运行时分析和操作类的结构。

反射在某些情况下非常有用,如动态加载类、在运行时解析和执行外部配置的类、实现框架和工具等。但是,由于反射涉及到在运行时进行动态操作,因此可能会带来一些性能上的损失。

反射的特性:

  • 获取类的信息:可以获取类的名称、包名、父类、接口、字段、方法等信息。
  • 实例化对象:可以通过类的构造函数动态地创建对象实例。
  • 调用方法和访问字段:可以通过方法名称和参数类型动态地调用方法,也可以通过字段名称访问和修改字段的值。
  • 处理注解:可以获取和解析类、方法、字段上的注解信息。

获取类的Class对象:

  • 使用类的.class属性:Class<?> clazz = MyClass.class;
  • 使用Class.forName()方法:Class<?> clazz = Class.forName("com.example.MyClass");com.example.MyClass为类实际的路径。
  • 使用对象的.getClass()方法:Class<?> clazz = myObject.getClass();

获取类的信息:
获取类信息之前需要先获取到class对象

  • 获取类的名称:String className = clazz.getName();
  • 获取类的修饰符:int modifiers = clazz.getModifiers();
  • 获取类的父类:Class<?> superClass = clazz.getSuperclass();
  • 获取类的接口:Class<?>[] interfaces = clazz.getInterfaces();
  • 获取类的共有构造函数:Constructor<?>[] constructors = clazz.getConstructors();
  • 获取类的共有方法:Method[] methods = clazz.getMethods();
  • 获取类的共有字段:Field[] fields = clazz.getFields();
  • 获取类的所有构造函数:Constructor<?>[] constructors = clazz.getDeclaredConstructors();
  • 获取类的所有方法:Method[] methods = clazz.getDeclaredMethods();
  • 获取类的所有字段:Field[] fields = clazz.getDeclaredFields();

实例化对象:
实例化对象之前需要先获取到class对象

  • 通过无参构造函数实例化:Object obj = clazz.newInstance();(在Java 9之后已过时)
  • 通过有参构造函数实例化:首先获取构造函数对象(constructors),然后使用构造函数的newInstance()方法。

调用方法和访问字段:
通过Method和Field对象调用方法和访问字段

  • 调用方法:首先获取方法对象,然后使用方法的invoke()方法调用方法。
  • 访问字段:首先获取字段对象,然后使用字段的get()和set()方法访问和修改字段的值。

在这里插入图片描述

Logo

科技之力与好奇之心,共建有温度的智能世界

更多推荐