IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> Java中的反射(Reflection) -> 正文阅读

[PHP知识库]Java中的反射(Reflection)

反射是Java被视为准动态语言的关键,反射机制允许程序在执行期间借助Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及其方法(包括private关键字修饰的)

想要获取或操作类创建的对象的内部属性及其方法,首先就要获取该类的Class对象,该类的Class对象是在初始化的时候创建的

1、获得类的Class对象

public class TestReflection {
    public static void main(String[] args) throws ClassNotFoundException {
        //方式一:通过实例化对象获得
        Class c1 = new TestReflection().getClass();
        //方式二:forName方法获得
        Class c2 = Class.forName("com.hu.www.reflection.TestReflection");
        //方式三:通过类名获得
        Class c3 = TestReflection.class;
        //输出并对比它们的hashCode
       	System.out.println(c1.hashCode() +"\n"+ c2.hashCode() +"\n"+ c3.hashCode());
    }
}

得到的3个hashCode都是相同的,说明一个类只有一个Class对象

2、获取运行时类的完整结构

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

//获取类的信息
public class TestReflection {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class aClass = Class.forName("com.hu.www.reflection.User");

        //1、获得类的名字
        System.out.println(aClass.getName());                   //获得包名 + 类名
        System.out.println(aClass.getSimpleName());             //获得类名

        Field[] declaredFields = aClass.getDeclaredFields();    //可以找到所有的属性,包括私有的
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

        //2、获得指定属性值
        Field name = aClass.getDeclaredField("name");           //可以找到private修饰的属性
        System.out.println(name);

        //3、获得类的所有方法
        methods = aClass.getDeclaredMethods();                  //获得本类的所有方法,包括私有的
        for (Method method : methods) {
            System.out.println("getDeclaredMethods:\t" + method);
        }

        //4、获得指定方法
        Method getName = aClass.getMethod("getName", null);
        Method setName = aClass.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);

        //5、获得指定的构造器
        Constructor[] constructors = aClass.getConstructors();
        Constructor[] declaredConstructors = aClass.getDeclaredConstructors();
        Constructor constructor = aClass.getConstructor(String.class, int.class, int.class);
        System.out.println(constructor);
    }
}

class User{
    private String name;
    private int id;
    private int age;

    public User() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

3、创建运行时类的对象并调用方法和属性

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

//通过反射动态地创建对象
public class TestReflection {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        //获得Class对象
        Class aClass = Class.forName("com.hu.www.reflection.User");

        //1、通过Class对象调用newInstance方法创建对象
        User user1 = (User)aClass.newInstance();
        System.out.println(user1);

        //2、通过Class对象获取构造器对象,构造器对象再调用newInstance方法创建对象
        Constructor constructor = aClass.getConstructor(String.class, int.class, int.class);
        User user2 = (User)constructor.newInstance("Hu", 001, 18);
        System.out.println(user2);

        //3、通过反射调用普通方法
        User user3 = (User)aClass.newInstance();
        //该类的Class对象通过反射获取方法
        Method setName = aClass.getMethod("setName", String.class);
        //获取到的方法对象调用invoke方法激活
        setName.invoke(user3,"Hu");
        System.out.println(user3.getName());

        //4、通过反射调用属性
        User user4 = (User)aClass.newInstance();
        //该类的Class对象通过反射获取属性
        Field name = aClass.getDeclaredField("name");
        //关闭权限检测
        name.setAccessible(true);
        //获取到的属性对象调用set方法设置,不能直接操作私有属性,需要关闭程序的安全检测
        name.set(user4,"hu");
        System.out.println(user4.getName());
    }
}

class User{
    private String name;
    private int id;
    private int age;

    public User() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

4、反射操作泛型

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

//通过反射获取泛型
public class TestReflection {
    
    public void test01(Map<String,User> map,List<User> list){
        System.out.println("test01");
    }

    public Map<String,User> test02(){
        System.out.println("test02");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        //1、获取参数的泛型信息
        //通过反射获取方法
        Method method = TestReflection.class.getMethod("test01", Map.class, List.class);
        //方法对象调用getGenericParameterTypes方法获取泛型类型
        Type[] genericParameterTypes = method.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            //循环输出所有泛型类型
            System.out.println(genericParameterType);
            //判断泛型的类型是否为ParameterizedType--参数化类型
            if (genericParameterType instanceof ParameterizedType){         
                //泛型类型为参数化类型,强转为ParameterizedType--参数化类型;并使用getActualTypeArguments方法获取它的真实参数信息
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    //循环输出所有泛型的真实类型
                    System.out.println(actualTypeArgument);
                }
            }
        }

        System.out.println("-----------------------------------------------------");

        //2、获取返回值的泛型信息
        //通过反射获取方法
        method = TestReflection.class.getMethod("test02",null);
        //方法对象调用getGenericReturnType方法获取泛型类型
        Type genericReturnType = method.getGenericReturnType();     
        //判断泛型的类型是否为ParameterizedType--参数化类型
        if (genericReturnType instanceof ParameterizedType){         
            //泛型类型为参数化类型,强转为ParameterizedType--参数化类型;并使用getActualTypeArguments方法获取它的真实参数信息
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                //循环输出所有泛型的真实类型
                System.out.println(actualTypeArgument);
            }
        }
    }
}

5、反射操作注解

package com.hu.www.reflection;

import java.lang.annotation.*;
import java.lang.reflect.Field;

//联系反射操作注解
public class TestReflection12 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //创建Student2类的Class对象
        Class aClass = Class.forName("com.hu.www.reflection.Student");

        //通过反射获得注解
        Annotation[] annotations = aClass.getAnnotations();
        //获得Student2类的注解
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //获得Student2类的注解value的值
        TableHu tableHu = (TableHu)aClass.getAnnotation(TableHu.class);
        System.out.println(tableHu.value());

        //获得类指定属性的注解
        Field field = aClass.getDeclaredField("name");
        FieldHu annotation = field.getAnnotation(FieldHu.class);
        //获得Student2类的name属性的注解信息
        System.out.println("列名:" + annotation.columnName());
        System.out.println("类型:" + annotation.type());
        System.out.println("长度:" + annotation.length());
    }
}

@TableHu("db_student")
class Student{
    @FieldHu(columnName = "db_id",type = "int",length = 10)
    private int id;
    @FieldHu(columnName = "db_age",type = "int",length = 10)
    private int age;
    @FieldHu(columnName = "db_name",type = "varchar",length = 3)
    private String name;

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

//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableHu{
    String value();
}

//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldHu{
    String columnName();
    String type();
    int length();
}
  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-22 14:26:09  更:2021-09-22 14:28:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:21:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码