Java反射例子汇总 Class Constructor Method Filed

Wesley13
• 阅读 551

一、反射概述

  在平常的开发中Java的反射技术很少被用到,一般我们都是使用公司封装或者开源框架。而反射技术已经被包含到底层框架了,因此我们很少接触到。但是有些框架的原理或者源码如果想读懂就必须要理解并会使用反射技术。例如:EventBus、BufferKnife、android的插件化等等都会用到。理解了反射技术能够帮助我们更快的理解相关框架,也可以增强我们开发人员的基本功。

  Java中的反射能做到什么?

  1.根据一个字符串的到一个类对象

  2.获取一个类的所有的共有、私有方法或者属性(包括静态的)

  3.可以对泛型进行反射

二、根据一个字符串得到Class

package com.yw.reflectjavalib;


/**
 * 获取类对象的三种方式
 */
public class ReflectDemoTest {
    /**
     * 程序的入口,main方法
     *
     * @param args
     */
    public static void main(String[] args) {
        LogUtil.e("根据一个字符串获取类全名");
        str2Class();
        LogUtil.e("使用Class.forName获取类全名");
        classForName();
    }

    /**
     * 根据一个字符串得到一个类
     */
    public static void str2Class() {
        String str = "hello world";
        Class classes = str.getClass();
        LogUtil.e(classes.getName());//
    }

    /**
     * 使用ClassForName获取类
     */
    public static void classForName() {
        try {
            Class str = Class.forName("java.lang.String");
            Class tv = Class.forName("com.yw.reflectjavalib.LogUtil");
            LogUtil.e(str.getName());
            LogUtil.e(tv.getName());
            //根据getSupperclass获取超类全名,由于LogUtil的超类是Object,所以Object会被打印
            LogUtil.e(str.getSuperclass().getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * 根据类的class属性获取类对象
     */
    public static void classAtb() {
        Class c = String.class;
        LogUtil.e(c.getName());
        LogUtil.e(c.getSuperclass().getName());
    }

}

三、反射构造方法,并创建实例

package com.yw.reflectjavalib;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

/**
 * 获取类的成员
 * 如:方法、属性、参数
 * create by yangwei
 * on 2020-02-07 14:48
 */
public class ClassMemberDemo {

    /**
     * 程序的入口main方法
     *
     * @param args
     */
    public static void main(String[] args) {
        //获取类的构造函数
        //获取类的所有构造函数
        Book book = new Book();
        //获取book类对象
        Class bookClass = book.getClass();
        //获取book类的所有的构造函数
        Constructor[] constructors = bookClass.getDeclaredConstructors();
        //打印出构造函数名称、修饰符以及构造函数的参数
        for (Constructor c : constructors) {
            int mod = c.getModifiers();//获取构造函数的修饰符
            LogUtil.e(Modifier.toString(mod) + ":" + c.getName());
            Class[] params = c.getParameterTypes();//获取构造函数的参数
            StringBuffer sb = new StringBuffer();
            for (Class cs : params) {
                sb.append(cs.getName()).append(",");
            }
            LogUtil.e(sb.toString());
        }

        //获取book类的无惨构造函数
        try {
            Constructor noC = bookClass.getDeclaredConstructor();
            int mod = noC.getModifiers();
            LogUtil.e(Modifier.toString(mod) + ":" + noC.getName());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //获取一个参数的构造函数
        try {
            Constructor oneC = bookClass.getDeclaredConstructor(String.class);
            int mod = oneC.getModifiers();
            LogUtil.e(Modifier.toString(mod) + ":" + oneC.getName());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //获取有两个参数的构造函数
        try {
            Constructor towC = bookClass.getDeclaredConstructor(String.class, String.class);
            int mod = towC.getModifiers();
            LogUtil.e(Modifier.toString(mod) + ":" + towC.getName());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        //通过Class实例化一个对象
        try {
            Constructor constructor = bookClass.getDeclaredConstructor();
            Object object = constructor.newInstance();
            Book book1 = (Book) object;
            book1.setBookName("《深入Java虚拟机》");
            LogUtil.e(book1.getBookName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //通过Class.forName实例化加载一个类,并实例化一个对象,并打印书本名称
        try {
            Class classBook = Class.forName("com.yw.reflectjavalib.Book");
            Constructor constructor = classBook.getDeclaredConstructor(String.class, String.class);
            Object object = constructor.newInstance("《深入Java虚拟机》", "001");
            Book book2 = (Book) object;
            LogUtil.e(book2.getBookName());
        } catch (Exception e) {
            e.printStackTrace();
        }


    }


}

四、反射方法(包括静态)

package com.yw.reflectjavalib;

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

/**
 * java反射方法操作
 * create by yangwei
 * on 2020-02-07 16:12
 */
public class ReflectMethodDemo {
    /**
     * 程序的入口main方法
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        //获取Book类的私有方法getBookId并执行这个私有方法
        Class bookClass = Book.class;
        //创建实例
        Constructor bookCon = bookClass.getDeclaredConstructor();
        Object object = bookCon.newInstance();
        //获取这个方法
        Method method = bookClass.getDeclaredMethod("getBookId", new Class[]{});
        //执行这个方法
        method.setAccessible(true);
        method.invoke(object, new Object[]{});


        //使用Class.forName。执行类的静态私有方法
        Class bookClass2 = Class.forName("com.yw.reflectjavalib.Book");
        Method method1 = bookClass2.getDeclaredMethod("write");
        method1.setAccessible(true);
        method1.invoke(null);//静态方法属于类本身,所以这块执行jinvoke的时候不需要带任何参数


        //获取book类的私有实例字段bookName并执行修改
        Class bookClass3 = Book.class;
        Constructor con3 = bookClass3.getDeclaredConstructor();
        Object obj3 = con3.newInstance();
        Field field = bookClass3.getDeclaredField("bookName");
        field.setAccessible(true);
        field.set(obj3, "《设计模式》");
        Method method2 = bookClass3.getDeclaredMethod("getBookName");
        method2.setAccessible(true);
        method2.invoke(obj3, new Object[]{});

        //后去book的私有静态字段并修改
        Class bookClass4 = Book.class;
        Constructor con4 = bookClass4.getDeclaredConstructor();
        Object obj4 = con4.newInstance();
        Field field1 = bookClass4.getDeclaredField("book");
        field1.setAccessible(true);
        field1.set(obj4, "你真坏");
        Object objf = field1.get(null);
        LogUtil.e(objf.toString());
    }


}

五、反射属性

package com.yw.reflectjavalib;

import java.lang.reflect.Field;

/**
 * 对属性进行反射并操作属性
 * create by yangwei
 * on 2020-02-16 17:04
 */
public class ReflectFiledDemo {
    public static void main(String[] args) {
//        optionFiled();
        optionStaticFiled();
    }

    /**
     * 操作属性
     */
    public static void optionFiled() {
        try {
            Class bookClass = Book.class;
            //创建Book实例
            Object bookObj = bookClass.newInstance();
            //获取book类的bookName属性
            Field field = bookClass.getDeclaredField("bookName");
            field.setAccessible(true);
            //获取Field中的值
            String bookName = (String) field.get(bookObj);
            System.out.println(bookName);

            //设置Field的值
            field.set(bookObj, "《大话数据结构》");
            //重新取出值
            String bookName2 = (String) field.get(bookObj);
            System.out.println(bookName2);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /**
     * 操作静态属性
     */
    public static void optionStaticFiled() {
        try {
            Class bookClass = Book.class;
            Field field = bookClass.getDeclaredField("book");
            field.setAccessible(true);
            //获取静态字段book的值
            String bookName = (String)field.get(null);
            System.out.println(bookName);
            //设置静态属性book的值
            field.set(null, "<深入Java虚拟机>");
            //重新取出值
            String bookName2 = (String) field.get(null);
            System.out.println(bookName2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

六、获取基本数据类型类对象

package com.yw.reflectjavalib;

/**
 * 基本数据类型获取类对象
 * create by yangwei
 * on 2020-02-07 14:42
 */
public class BaseTypeDemo {
    public static void main(String[] args) {
        Class bool = Boolean.TYPE;
        Class mByte = Byte.TYPE;
        Class mInt = Integer.TYPE;
        Class mShort = Short.TYPE;
        Class mLong = Long.TYPE;
        Class mFloat = Float.TYPE;
        Class mDouble = Double.TYPE;
        Class mChart = Character.TYPE;
        Class mVoid = Void.TYPE;
        LogUtil.e("boolean:" + bool.getName());
        LogUtil.e("byte:" + mByte.getName());
        LogUtil.e("int:" + mInt.getName());
        LogUtil.e("short:" + mShort.getName());
        LogUtil.e("long:" + mLong.getName());
        LogUtil.e("float:" + mFloat.getName());
        LogUtil.e("double:" + mDouble.getName());
        LogUtil.e("chart:" + mChart.getName());
        //我们常用的void也是有数据类型的,着点大家不要忽略了
        LogUtil.e("void:" + mVoid.getName());


    }


}

总结:说句实在话,Java的反射技术真心是晦涩难懂,初学者看着看着可能就懵逼了。为了方便操作在框架层面通常会把Java的反射技术封装成为一个类库,提供给开发者使用。

例如现成的:JOOR。下一节介绍手动封装反射类库(只有一个类),大家可以在做有反射项目的时候直接拿来使用。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java的反射机制
java中的反射可以将代码结构更加灵活,通过反射机制可以访问属性、方法和构造方法sun公司为我们提供的4大类反射:java.lang.reflect.methodjava.lang.Classjava.lang.reflect.modifierjava.lang.reflect.Constructor有以下几种方式:比如是Employ
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
35岁,真的是程序员的一道坎吗?
“程序员35岁是道坎”,“程序员35岁被裁”……这些话咱们可能都听腻了,但每当触及还是会感到丝丝焦虑,毕竟每个人都会到35岁。而国内互联网环境确实对35岁以上的程序员不太友好:薪资要得高,却不如年轻人加班猛;虽说经验丰富,但大部分公司并不需要太资深的程序员。但35岁危机并不是不可避免的,比如你可以不断精进技术,将来做技术管理或者
Wesley13 Wesley13
3年前
Java反射技术概述
1.什么是Java反射?  就是正在运行,动态获取这个类的所有信息2.反射机制的作用  a.反编译:.class.java  b.通过反射机制,访问Java对象的属性,方法,构造方法等3.反射机制的应用场景  Jdbc加载驱动  SpringIOC实现  Java框架4.创建对象的两种方式  a.直
Wesley13 Wesley13
3年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
3年前
Java反射的使用姿势一览
反射的学习使用日常的学习工作中,可能用到反射的地方不太多,但看看一些优秀框架的源码,会发现基本上都离不开反射的使用;因此本篇博文将专注下如何使用本片博文布局如下:1.反射是什么,有什么用,可以做什么2.如何使用反射3.实例:利用反射方式,获取一个类的所有成员变量的
京东云开发者 京东云开发者
6个月前
深入理解java反射机制及应用 | 京东物流技术团队
因为最近项目中经常有java反射的使用,而其中的IOC、动态代理用到了反射,因此趁这个机会来总结一下关于Java反射的一些知识,复习一下。本篇基于JDK1.8。java反射机制是什么反射原理Java反射机制(JavaReflection)是Java的特征之