Java的反射机制(应用篇)
Java的的反射机制,是一个很难但却比较有用的概念。反射机制经常出现在框架设计中,大神说:反射是框架设计的灵魂,也就是说要想看懂框架的源代码,必须得掌握反射机制。
作为初学者的我,觉得至少应该掌握它日常得几种用法。下面,继续接地气,说说反射机制的应用。
一、什么是Java Reflection?
反射机制,是指程序在运行过程中借助Reflection API来取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
注意:一定是运行过程中,不过这也很容易理解,“反射”凭感觉就可以认为这是一个动态的机制。关于反射机制,在Java中涉及到一个类——Class类。程序从源代码编写到执行的过程,如下图(图片来源于网络):

反射机制的使用前提:必须先得到字节码,前面所提的Class类就是用于表示.class文件(字节码)。
二、反射机制的作用
1.在运行时判断任意一个对象所属的类
2.在运行时构造任意一个类的对象
3.在运行时判断任意一个类所具有的成员变量和方法
4.在运行时调用任意一个对象的成员变量和方法
5.生成动态代理(比较难)
Reflection API:(主要的API)

反射的目的,就是要在程序运行时把类中的各种成分(如属性,构造方法,方法等等)分解成一个个的对象。那么,首先应该获取到‘类’,方法主要有三种,严格来讲有四种,而java.lang.Class这个类主要就是用来分解类中的对象。
接下来分析,获取运行时类的三种重要方式。
记住,得到的运行时类就是Class类型的实际对象,Class这个类是没有公共的构造方法的。
方法一:Class类中的静态方法forName("类名") ,已知Person是一个定义好的类,下同。
Class cs = Class.forName("Person");
方法二:Object超类中的getClass()方法
Person p=new Person(18,"90");
Class cs1 =p.getClass();
方法三:任何数据类型(包含基本数据类型)都有一个静态属性class
Person p=new Person(18,"90");
Class cs2 =Person.class;
Class自己本身是一个类,由于它没有公开的构造方法,因此它的对象只能由系统建立,并且任何一个类在JVM中只有一个实例。实际上一个Class对象对应
的是一个加载到JVM中的一个.class文件;每个类的实例都会记得自己是由哪个 Class 实例所生成;通过Class对象可以得到其对应类完整的结构。
Class有许多方法,使用时需要参照API文档。

这里省略Method、Constructor、Field等类的介绍,参照API,那是权威。哈哈!
三、反射的应用
主要应用于动态代理,代理是一种设计模式,还有静态代理,静态代理比较常见。
首先学习一下静态代理(代理实现的一般模式):首先创建一个接口(JDK代理都是面向接口的),然后创建具体实现类来实现这个接口,在创建一个代理
类同样实现这个接口,不同之处在于,具体实现类的方法中需要将接口中定义的方法的业务逻辑功能实现,而代理类中的方法只要调用具体类中的对应方法即
可,这样我们在需要使用接口中的某个方法的功能时直接调用代理类的方法即可,将具体的实现类隐藏在底层。
package com.rdst.staticDL;
//静态代理模式
//接口
interface ClothFactory{
void productCloth();
}
//被代理类
class NikeClothFactory implements ClothFactory{
@Override
public void productCloth() {
System.out.println("Nike工厂生产一批衣服");
}
}
//代理类
class ProxyFactory implements ClothFactory{
ClothFactory cf;
//创建代理类的对象时,实际传入一个被代理类的对象
public ProxyFactory(ClothFactory cf){
this.cf = cf;
} @Override
public void productCloth() {
System.out.println("代理类开始执行,收代理费$1000");
cf.productCloth();
} } public class TestClothProduct {
public static void main(String[] args) {
NikeClothFactory nike = new NikeClothFactory();//创建被代理类的对象
ProxyFactory proxy = new ProxyFactory(nike);//创建代理类的对象
proxy.productCloth();
}
}
看见没,静态代理是在编译前就将接口、实现类、代理类一股脑儿全部手动完成。
再来学习一下动态代理:动态代理的思维模式与之前的静态代理是一样的,也是面向接口进行编码,创建代理类将具体类隐藏解耦,不同之处在于代理类的
创建时机不同,动态代理需要在运行时因需实时创建。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//动态代理的使用,体会反射是动态语言的关键
interface Subject {
void action();
}
// 被代理类
class RealSubject implements Subject {
public void action() {
System.out.println("我是被代理类!");
}
}
class MyInvocationHandler implements InvocationHandler {
Object obj;// 实现了接口的被代理类的对象的声明 // ①给被代理的对象实例化②返回一个代理类的对象
public Object blind(Object obj) {
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
.getClass().getInterfaces(), this);
}
//当通过代理类的对象发起对被重写的方法的调用时,都会转换为对如下的invoke方法的调用
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//method方法的返回值时returnVal
Object returnVal = method.invoke(obj, args);
return returnVal;
}
}
public class TestProxy {
public static void main(String[] args) {
//1.被代理类的对象
RealSubject real = new RealSubject();
//2.创建一个实现了InvacationHandler接口的类的对象
MyInvocationHandler handler = new MyInvocationHandler();
//3.调用blind()方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象。
Object obj = handler.blind(real);
Subject sub = (Subject)obj;//此时sub就是代理类的对象
sub.action();//转到对InvacationHandler接口的实现类的invoke()方法的调用
//再举一例
NikeClothFactory nike = new NikeClothFactory();
ClothFactory proxyCloth = (ClothFactory)handler.blind(nike);//proxyCloth即为代理类的对象
proxyCloth.productCloth();
}
}
面向对象编程的多态,代理的核心知识还是向上转型。
Java的反射机制(应用篇)的更多相关文章
- java的反射机制(第二篇)
本文转载自:http://c.biancheng.net/cpp/html/1781.html 要理解RTTI在Java中的工作原理,首先必须知道类型信息在运行时是如何表示的,这项工作是由“Class ...
- java的反射机制(第三篇)
本文转载自:http://c.biancheng.net/cpp/html/1782.html Person p=new Person();这是什么?当然是实例化一个对象了.可是这种实例化对象的方法存 ...
- Java高级特性——反射机制(第一篇)
——何为动态语言,何为静态语言?(学习反射知识前,需要了解动态语言和静态语言) 动态语言 >是一类在运行时可以改变其结构的语言,例如新的函数.对象.甚至是代码可以被引进,已有的函数可以被删除或者 ...
- Java 类反射机制分析
Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...
- Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别
一.Java的反射机制 每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图: 其中
- 深入浅出学习hibernate框架(三):java的反射机制
上篇博客写到了JDBC的基本操作,今天准备写一篇关于JAVA反射机制的文章,因为java的反射机制和上一篇JDBC都是Hibernate框架的基本要素.在Hibernate的运行机制中,这两块的内容正 ...
- 014 Java的反射机制
作者:nnngu GitHub:https://github.com/nnngu 博客园:http://www.cnblogs.com/nnngu 简书:https://www.jianshu.com ...
- java的反射机制
一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...
- java笔记--反射机制之基础总结与详解
一.反射之实例化Class类的5种方式: java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型). 对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象 ...
- JAVA的反射机制学习笔记(二)
上次写JAVA的反射机制学习笔记(一)的时候,还是7月22号,这些天就瞎忙活了.自己的步伐全然被打乱了~不能继续被动下去.得又一次找到自己的节奏. 4.获取类的Constructor 通过反射机制得到 ...
随机推荐
- Ubuntu配置apache2.4配置虚拟主机遇到的问题
update: 偶然看到了 apache的更新说明,直接贴个地址过来吧. http://httpd.apache.org/docs/2.4/upgrading.html 最近想把web开发目录从/va ...
- ftp put get 的使用方法
首先:ftp user@ip 登录到远程主机 成功后,输入ls,如下: ftp> ls 可以得到远程主机的本地目录. 一:get命令(从远程主机下载文件到本机): ftp> get (re ...
- DLX精确覆盖与重复覆盖模板题
hihoCoder #1317 : 搜索四·跳舞链 原题地址:http://hihocoder.com/problemset/problem/1317 时间限制:10000ms 单点时限:1000ms ...
- python 基础 9.7 创建表
一. 创建表 #/usr/bin/python #-*- coding:utf-8 -*- #@Time :2017/11/22 18:05 #@Auther :liuzhenchuan #@Fi ...
- [CMD]重启电脑
https://zhidao.baidu.com/question/686086701903450132.html bat是批处理,可以调用关机命令关机. 制作方法如下: 打开记事本程序: 输入如下内 ...
- poj1408(求线段交点)
求出所有线段的交点,然后利用叉乘求四边形面积即可. // // main.cpp // poj1408 // // Created by 陈加寿 on 15/12/31. // Copyright ( ...
- Zipper (DP)
Zipper Given three strings, you are to determine whether the third string can be formed by combining ...
- vue-cli (vue脚手架)
vue-cli(脚手架):它可以自动生成目录 1.在网速不佳的情况下可以安装cnpm(淘宝镜像)如果网速快可以不用安装cnpm直接进行下一步操作 第一步:在命令行执行(全局安装cnpm) npm in ...
- cocos2dx使用cocostudio导出的ui
local uilocal function createLayerUI() if not ui then ui=cc.Layer:create(); createLayerUI=nil; end r ...
- 次小生成树Tree
次小生成树Treehttps://www.luogu.org/problemnew/show/P4180 题目描述 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正 ...