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

① 反射的简单解释

② 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;
} }

① 使用反射构建对象

 private static void demo2() throws Exception {

         Class.forName("test.reflect.Airplane").newInstance();

         Airplane.class.newInstance();

         Airplane.class.getDeclaredConstructor(new Class[]{}).newInstance(); // new Class[]{} 使用无惨构造函数
}

所有类都是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());
}

结果

 -------getFields-------

 publicField

 superField

 -------getDeclaredFields-------

 name

 price

 publicField

 protectedField

 --------getDeclaredField(String)------

 name

③ 获取方法

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()); }

结果 :

 ------getMethods--------
run
getName
setName
getPrice
setPrice
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
------getDeclaredMethods--------
run
getName
setName
protectedMethod
privateMethod
getPrice
setPrice
--------getDeclaredMethod------
getName

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

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<Airplane> c = Airplane.class.getDeclaredConstructor(new Class[]{String.class, int.class});
print(c.getName()); }
// 结果
-------getConstructors-------
test.reflect.Airplane
-------getDeclaredConstructors-------
test.reflect.Airplane
test.reflect.Airplane
-------getDeclaredConstructor(Class<?>)-------
test.reflect.Airplane HighSpeedTrain构造函数是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.HighSpeedTrain
test.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);
}
// 结果
4
54

四、反射应用场景

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

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

java反射快速入门(一)的更多相关文章

  1. java反射快速入门(二)

    上一遍博文 , 简单介绍java 反射的常用接口,本遍博文, 我会结合项目开发的实际例子讲解下 java反射的使用 现在有个需求, 要将一个对象转换成xml格式, 或者将一串xml转换一个对象, 这时 ...

  2. java反射快速入门

    笔记记在了掘金,发现掘金的markdown编辑器比博客园样式要好看不少 https://juejin.im/post/5d4e575af265da03e4674e9f

  3. JAVA WEB快速入门之从编写一个基于SpringBoot+Mybatis快速创建的REST API项目了解SpringBoot、SpringMVC REST API、Mybatis等相关知识

    JAVA WEB快速入门系列之前的相关文章如下:(文章全部本人[梦在旅途原创],文中内容可能部份图片.代码参照网上资源) 第一篇:JAVA WEB快速入门之环境搭建 第二篇:JAVA WEB快速入门之 ...

  4. JAVA WEB快速入门之从编写一个基于SpringMVC框架的网站了解Maven、SpringMVC、SpringJDBC

    接上篇<JAVA WEB快速入门之通过一个简单的Spring项目了解Spring的核心(AOP.IOC)>,了解了Spring的核心(AOP.IOC)后,我们再来学习与实践Maven.Sp ...

  5. java反射机制入门01

    java反射机制入门是我从极客学院的视频中学习的. 1.反射机制背景概述 反射(Reflection)是java被视为动态(或准动态)语言的一个关键性质.反射机制指的是程序在运行时能够获取任何类的内部 ...

  6. Java Web快速入门——全十讲

    Java Web快速入门——全十讲 这是一次培训的讲义,就是我在给学生讲的过程中记录下来的,非常完整,原来发表在Blog上,我感觉这里的学生可能更需要. 内容比较长,你可以先收藏起来,慢慢看. 第一讲 ...

  7. 大白话说Java反射:入门、使用、原理

    文章首发于[博客园-陈树义],点击跳转到原文<大白话说Java反射:入门.进阶.原理> 反射之中包含了一个「反」字,所以想要解释反射就必须先从「正」开始解释. 一般情况下,我们使用某个类时 ...

  8. JAVA WEB快速入门之通过一个简单的Spring项目了解Spring的核心(AOP、IOC)

    接上篇<JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构.调试.部署>,通过一个简单的JSP WEB网站了解了JAVA WEB相关的知识,比如:Ser ...

  9. JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构、调试、部署

    接上篇<JAVA WEB快速入门之环境搭建>,在完成了环境搭建后(JDK.Tomcat.IDE),现在是万事具备,就差写代码了,今天就来从编写一个JSP WEB网站了解JSP WEB网站的 ...

随机推荐

  1. No ongoing transaction. Did you forget to call multi?

    2016-10-21 14:41:47,551 [ERROR] [http-nio-8032-exec-2] TransactionSynchronizationUtils:171 - Transac ...

  2. C中如何调用C++函数、类内函数 \混编\链接

    在C中如何调用C++函数的问题,简单回答是将函数用extern "C"声明,当被问及如何将类内成员函数声明时,一时语塞,后来网上查了下,网上有一翻译C++之父的文章可以作为解答,遂 ...

  3. linux 用grep匹配横线

    file的内容如下: ADSFADSFSDFASDFJKJK----------------------------------------ADSFADSFSDFASDFJKJK----------- ...

  4. 转 Android adb root权限

    永久root带文件 因为开发需要,我经常会用到adb这个工具(Android Debug Bridge),我们都知道adb shell默认是没有root权限的,修改系统文件就很不方便了,adb pus ...

  5. poj 1442 Black Box(堆 优先队列)

    题目:http://poj.org/problem?id=1442 题意:n,m,分别是a数组,u数组的个数,u[i]w为几,就加到a几,然后输出第i 小的 刚开始用了一个小顶堆,超时,后来看了看别人 ...

  6. POJ3921

    搜索 每次找出最短路 如果小于等于k 那么必定这里有一点是要被删掉的 枚举这个最短路径上的每一个点 (一般不会超过20) 将其相邻边删除 用dijskra求最短路径并且保存即可 深度搜索 #inclu ...

  7. Repeater实例应用

    在实际开发过程中,涉及到数据绑定,分页,以及一对多展示数据时,遇到这样的需求我们怎么解决呢?下面以帖子展示来逐一说明. 帖子主要由两部分组成,第一部分是发帖人的原创内容部分,第二部分是用户评论部分,这 ...

  8. [CF 471C] MUH and House of Cards

    C. MUH and House of Cards   Polar bears Menshykov and Uslada from the zoo of St. Petersburg and elep ...

  9. 【转】@Override must override a superclass method 问题解决

    原文网址:http://www.blogjava.net/anchor110/articles/339352.html 如果在使用Eclipse开发Java项目时,在使用 @Override 出现以下 ...

  10. css页面重构面试题

    偶然间又看到博客园中这两道页面重构面试题.题一:分别用2个DIV,3个DIV,5个DIV实现水平垂直均居中显示一个宽50px,高200px的正十字架.思路:水平垂直均居中的实现,当然非absolute ...