博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java反射快速入门(一)
阅读量:5819 次
发布时间:2019-06-18

本文共 6721 字,大约阅读时间需要 22 分钟。

本文会从以下几个方面讲起

① 反射的简单解释

② java反射的API接口 及 demo

③ 反射的优缺点、应用场景

一、什么是反射?

java反射:在程序运行中动态获取类的信息,及动态调用对象的方法,这就是java反射

二、java反射的API接口

常用API接口规律  

getXX() : 获取类本身 及父类的public属性、方法等

getDeclaredXX() :  获取类本身的所有私有保护属性、方法等

getDeclaredXX(String name) : 获取类本身的指定name的私有、保护属性、方法等(getDeclaredConstructors 较特殊, 还可以获取public)

以下demo涉及到的类先给出咯

package test.reflect;// 父类public abstract class Vehicle {        public String superField = "父类属性";        private String superPrivateField = "父类私有属性";        protected String superProtectedField = "父类保护属性";    public abstract void run();        private void superPrivateMethod() {            }        protected void superProteMethod() {            }}// 飞机子类package test.reflect;public class Airplane extends Vehicle {    private String name;    private int price;        public String publicField;        protected String protectedField;        private Airplane() {        System.out.println("Airplane 构造函数");    }        public Airplane(String name, int price) {        this.name = name;        this.price = price;    }    public void run() {        System.out.println("春节,坐飞机飞回家~~~");    }        protected void protectedMethod() {            }        private void privateMethod() {            }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getPrice() {        return price;    }    public void setPrice(int price) {        this.price = price;    }}// 高铁子类package test.reflect;public class HighSpeedTrain extends Vehicle {    private String name;    private int price;    public void run() {        System.out.println("春节,坐高铁溜回家~~~");    }        private HighSpeedTrain() {            }        protected HighSpeedTrain(String name) {            }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getPrice() {        return price;    }    public void setPrice(int price) {        this.price = price;    }}

① 使用反射构建对象

1 private static void demo2() throws Exception {2         3         Class.forName("test.reflect.Airplane").newInstance();4         5         Airplane.class.newInstance();6         7         8         Airplane.class.getDeclaredConstructor(new Class[]{}).newInstance(); // new Class[]{} 使用无惨构造函数9     }

所有类都是Class对象, 获取class 有以下三种

Class.forName(包名+类名)

xx.class

xx.getClass

②  获取属性 

getFields() : 获取父子类的所有public属性

getDeclaredFields() : 获取子类的所有private\protected属性

demo如下 : 

private static void demo3() throws Exception {        //  获取父子类的所有public属性        Field[] fields = Airplane.class.getFields();        for(Field f : fields) {            print(f.getName());        }        // 获取子类的所有private\protected属性        Field[] fields2 = Airplane.class.getDeclaredFields();        for(Field f : fields2) {            print(f.getName());        }        // 获取指定属性名的属性        Field f = Airplane.class.getDeclaredField("name");        print(f.getName());    }

结果

1 -------getFields------- 2  3 publicField 4  5 superField 6  7 -------getDeclaredFields------- 8  9 name10 11 price12 13 publicField14 15 protectedField16 17 --------getDeclaredField(String)------18 19 name
View Code

 

③ 获取方法 

getMethods() : 获取父子类的所有public方法

getDeclaredMethods() : 获取子类的所有private\protected方法

demo如下 : 

private static void demo4() throws Exception {        Method[] methods = Airplane.class.getMethods();        for(Method m : methods) {            print(m.getName());        }                        Method[] methods2 = Airplane.class.getDeclaredMethods();        for(Method m : methods2) {            print(m.getName());        }                        Method m = Airplane.class.getDeclaredMethod("getName");        print(m.getName());            }

结果 :

1 ------getMethods-------- 2 run 3 getName 4 setName 5 getPrice 6 setPrice 7 wait 8 wait 9 wait10 equals11 toString12 hashCode13 getClass14 notify15 notifyAll16 ------getDeclaredMethods--------17 run18 getName19 setName20 protectedMethod21 privateMethod22 getPrice23 setPrice24 --------getDeclaredMethod------25 getName
View Code

 

④  获取构造函数(和前面有所区别,指类本身的构造函数,不包括父类)

getConstructors() : 获取public构造函数

getDeclaredConstructors() : 获取子类的所有private\protected\public构造函数 (注意 : 这里还能获取public的, 和 getDeclaredFields getDeclaredMethods 不同)

demo如下 :

Airplane构造函数是public修饰private static void demo5() throws Exception {                Constructor
[] constructors = Airplane.class.getConstructors(); for(Constructor c : constructors) { print(c.getName()); } System.out.println("--------------"); Constructor
[] constructors2 = Airplane.class.getDeclaredConstructors(); for(Constructor c : constructors2) { print(c.getName()); } System.out.println("--------------"); Constructor
c = Airplane.class.getDeclaredConstructor(new Class[]{String.class, int.class}); print(c.getName()); }// 结果-------getConstructors-------test.reflect.Airplane-------getDeclaredConstructors-------test.reflect.Airplanetest.reflect.Airplane-------getDeclaredConstructor(Class
)-------test.reflect.AirplaneHighSpeedTrain构造函数是private protected修饰private static void demo6() throws Exception { System.out.println("------getConstructors--------"); Constructor
[] constructors = HighSpeedTrain.class.getConstructors(); for(Constructor c : constructors) { print(c.getName()); } System.out.println("------getDeclaredConstructors--------"); Constructor
[] constructors2 = HighSpeedTrain.class.getDeclaredConstructors(); for(Constructor c : constructors2) { print(c.getName()); } }// 结果------getConstructors--------------getDeclaredConstructors--------test.reflect.HighSpeedTraintest.reflect.HighSpeedTrain

 

  三、java 反射的优缺点

① 优点 :

  • 在运行时检测对象的类型;
  • 动态构造某个类的对象;
  • 检测类的属性和方法;
  • 任意调用对象的方法;
  • 修改构造函数、方法、属性的可见性;
  • 以及其他。

② 缺点 :性能下降 . 由于反射涉及动态解析类型, 所以使用反射构建对象 比 直接构造对象性能差了一两个数量级

private static void demo7() throws Exception {                long start = System.currentTimeMillis();        for(int i = 0; i <  10000; i++) {            Airplane a = new Airplane();        }        System.out.println(System.currentTimeMillis() - start);                start = System.currentTimeMillis();        for(int i = 0; i <  10000; i++) {            Airplane a2 = Airplane.class.getDeclaredConstructor().newInstance();        }        System.out.println(System.currentTimeMillis() - start);    }// 结果454

 

四、反射应用场景

① junit test, 使用注解@Test , 底层无非是使用反射来获取加了Test的注解标识,从而获取到测试方法。

② spring aop思想, spring 加载bean xml 配置文件, 使用 Class.forName(String beanName) 动态构造bean, 也都是反射的经典例子。

 

转载于:https://www.cnblogs.com/chenmo-xpw/p/5182950.html

你可能感兴趣的文章
四、配置开机自动启动Nginx + PHP【LNMP安装 】
查看>>
Linux 目录结构及内容详解
查看>>
OCP读书笔记(24) - 题库(ExamD)
查看>>
解决Unable to load R3 module ...VBoxDD.dll (VBoxDD):GetLastError=1790
查看>>
.net excel利用NPOI导入oracle
查看>>
$_SERVER['SCRIPT_FLENAME']与__FILE__
查看>>
My97DatePicker 日历插件
查看>>
hive基本操作与应用
查看>>
excel快捷键设置
查看>>
poj3692
查看>>
python之信号量【Semaphore】
查看>>
html5纲要,细谈HTML 5新增的元素
查看>>
Android应用集成支付宝接口的简化
查看>>
[分享]Ubuntu12.04安装基础教程(图文)
查看>>
WCF
查看>>
django 目录结构修改
查看>>
win8 关闭防火墙
查看>>
Android实例-录音与回放(播放MP3)(XE8+小米2)
查看>>
CSS——(2)与标准流盒模型
查看>>
MYSQL 基本SQL语句
查看>>