反射——获取Class对象的三种方法,构造器、成员变量、方法

 作用

学习如何获取类的信息,操作它们

 获取class对象的三种方法

package com.zz.reflection;

import com.zz.Interface.studentMannger.ClassManager;

//目标:获取class对象
public class Test1Class {
    public static void main(String args[]) throws ClassNotFoundException {
        Class c1 = Student.class;//获取Class对象 --字节码
        System.out.println(c1.getName());//全类名
        System.out.println(c1.getSimpleName());//简名:Student

        Class c2 = Class.forName("com.zz.reflection.Student");
        System.out.println(c2 == c1);

        Student s = new Student();
        Class c3 = s.getClass();
        System.out.println(c3 == c2);
    }
}

获取类的构造器,并对其操作 

package com.zz.reflection;

import com.zz.Interface.studentMannger.ClassManager;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.sql.Connection;

/**
 * 目标:掌握获取类的构造器,并对其进行操作
 */
public class Test2Constructor {

    @Test
    public void testGetConstructors() {
        //1.反射第一步:必须先得到这个类的Class对象
        Class c = Student.class;

        //2.获取类的全部构造器
        // Constructor[] constructors = c.getConstructors();只能获取public修饰的构造器
        Constructor[] constructors = c.getDeclaredConstructors();//获取全部构造器--推荐
        //3.遍历数组中的每个构造器对选哪个
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
        }
    }

        @Test
        public void testGetConstructor() throws Exception {
            //1.反射第一步:必须先得到这个类的Class对象
            Class c = Student.class;

            //2.获取某个构造器,无参构造器--
            // Constructor constructor = c.getConstructor();只能取到public修饰的构造器
            Constructor constructor = c.getDeclaredConstructor();//可以取到任意修饰符修饰的构造器
            System.out.println(constructor.getName() + "==>" + constructor.getParameterCount());

            constructor.setAccessible(true);//禁止检查访问权限
            //初始化对象
            Student student = (Student)constructor.newInstance();
            System.out.println(student);

            //3.获取有参数的构造器
            Constructor constructor2 = c.getDeclaredConstructor(String.class, int.class);
            System.out.println(constructor2.getName() + "==>" + constructor2.getParameterCount());
            Student student1 = (Student)constructor2.newInstance("小明", 3);
            System.out.println(student1);
        }
}

 获取类的成员变量

package com.zz.reflection;

import com.zz.Interface.studentMannger.ClassManager;
import org.junit.Test;

import java.lang.reflect.Field;

/**
 * 目标:获取类的成员变量,并对其操作
 */
public class Test3Field {
    @Test
    public void testGetFields() throws NoSuchFieldException, IllegalAccessException {
        //1.反射第一步,必须是先得到类的Class对象
        Class s = Student.class;

        //2.获取类的全部成员变量
        Field[] fields = s.getDeclaredFields();

        //3.遍历这个成员变量数组
        for (Field field : fields) {
            System.out.println(field.getName() + "==>" + field.getType());
        }
        //4.定位某个成员变量
        Field fName = s.getDeclaredField("name");
        System.out.println(fName.getName() + "===>" + fName.getType());

        //赋值
        Student student = new Student();
        fName.setAccessible(true);//禁止访问控制权限
        fName.set(student, "小红");
        System.out.println(student);

        //取值
        String name = (String)fName.get(student);
        System.out.println(name);
    }
}

获取成员方法 

package com.zz.reflection;

import org.junit.Test;

import java.lang.reflect.Method;

public class Test4Method {
    @Test
    public void testGetMethods() throws Exception {
        //1.反射第一步,先得到Class对象
        Class c = Cat.class;
        
        //2.获取类的全部成员方法
        Method[] methods = c.getDeclaredMethods();

        //3.遍历这个数组中的每个方法对象
        for (Method method : methods) {
            System.out.println(method.getName() + "==>" + method.getParameterCount()
            + "===>" + method.getReturnType());
        }

        //4.获取某个方法对象
        Method run = c.getDeclaredMethod("run");//无参数的
        System.out.println(run.getName() + "->" + run.getParameterCount() + "->" +run.getReturnType());

        Method eat = c.getDeclaredMethod("eat", String.class);
        System.out.println(eat.getName() + "->" + eat.getReturnType());

        Cat cat = new Cat();
        run.setAccessible(true);
       Object rs = run.invoke(cat);//调用无参数的run方法,用cat对象触发调用的
        System.out.println(rs);

        eat.setAccessible(true);
        String rs2 = (String)eat.invoke(cat, "鱼儿");
        System.out.println(rs2);

    }
}

 应用场景

案例 

 

package com.zz.reflection;

//目标:使用反射技术,设计一个保存对象的简易版框架
import org.junit.Test;

public class Test5Frame {
    @Test
    public void save() throws Exception {
        Student s1 = new Student("tom", 12, '男', 127.3, "打球");
        Teacher t1 = new Teacher("李老师", 4567);

        //需求:把任意对象的字段名和对应的值等信息,
        ObjectFrame.saveObject(s1);
        ObjectFrame.saveObject(t1);
    }
}

 

package com.zz.reflection;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;

public class ObjectFrame {
    //目标:保存任意对象的字段和其数据到文件中去
    public static void saveObject(Object obj) throws Exception {
        PrintStream ps = new PrintStream(new FileOutputStream("data.txt",true));
        //obj是任意对象
        Class c = obj.getClass();
        String cName = c.getSimpleName();
        ps.println("===========" + cName + "=========");
        //2.从这个类中提取它的全部成员变量
        Field[] fields = c.getDeclaredFields();
        //3.遍历每个成员变量
        for (Field field : fields) {
            //拿到成员变量的名字
            String name = field.getName();
            //5.拿到这个成员变量在对象中的数据
            field.setAccessible(true);
            String value = (String)(field.get(obj) + "");
            ps.println(name + "=" + value);
        }
        ps.close();
    }
}

 

最近更新

  1. leetcode705-Design HashSet

    2024-04-03 09:08:02       5 阅读
  2. Unity发布webgl之后打开streamingAssets中的html文件

    2024-04-03 09:08:02       5 阅读
  3. vue3、vue2中nextTick源码解析

    2024-04-03 09:08:02       6 阅读
  4. 高级IO——React服务器简单实现

    2024-04-03 09:08:02       5 阅读
  5. 将图片数据转换为张量(Go并发处理)

    2024-04-03 09:08:02       4 阅读
  6. go第三方库go.uber.org介绍

    2024-04-03 09:08:02       6 阅读
  7. 前后端AES对称加密 前端TS 后端Go

    2024-04-03 09:08:02       7 阅读

热门阅读

  1. 负载均衡:实现高效稳定的网络服务

    2024-04-03 09:08:02       5 阅读
  2. Vue3: 如何在 ref() 与 reactive() 之间做正确选择?

    2024-04-03 09:08:02       4 阅读
  3. ActiViz中的图像处理vtkImageViewer2

    2024-04-03 09:08:02       4 阅读
  4. 集创赛分析(图像处理部分)

    2024-04-03 09:08:02       3 阅读
  5. ActiViz中的图像处理vtkImageActor

    2024-04-03 09:08:02       6 阅读
  6. 设计模式面试题(一)

    2024-04-03 09:08:02       6 阅读
  7. 鸿蒙原生应用开发-网络管理Socket连接(二)

    2024-04-03 09:08:02       5 阅读
  8. Amazon API Gateway 配置自定义域名

    2024-04-03 09:08:02       4 阅读
  9. FPGA在深度学习领域的应用的优势

    2024-04-03 09:08:02       6 阅读
  10. 安装编译cpprest sdk

    2024-04-03 09:08:02       4 阅读
  11. SSH中私钥和公钥的使用

    2024-04-03 09:08:02       5 阅读
  12. Echart(多雷达图展示)

    2024-04-03 09:08:02       4 阅读