Java反射开窍--1
1.通过案例引出反射并体会反射的好处
案例:美团外卖 --->付款 ---》要么用微信支付 要么用支付宝支付
package com.zhaoss.test01;
//接口的制定方:美团外卖
public interface Mtwm {
//在线支付功能:
void payOnline();
}
public class WeChat implements Mtwm {
@Override
public void payOnline() {
//具体实现微信支付的功能:
System.out.println("我已经点了外卖,正在使用微信支付");
}
}
public class AliPay implements Mtwm {
@Override
public void payOnline() {
//具体实现微信支付的功能:
System.out.println("我已经点了外卖,正在使用支付宝进行支付");
}
}
public class BankCard implements Mtwm {
@Override
public void payOnline() {
//具体实现微信支付的功能:
System.out.println("我已经点了外卖,正在使用招商银行信用卡支付");
}
}
测试类:
public class Test {
public static void main(String[] args) {
//定义一个字符串,用来模拟前台的支付方式:
String str = "微信";
//str.equals("微信")---避免空指针异常,编程习惯要好,常量在左边
if ("微信".equals(str)) {
// 微信支付:
pay(new WeChat());
}
if ("支付宝".equals(str)) {
//支付宝支付:
pay(new AliPay());
}
if ("招商银行".equals(str)) {
pay(new BankCard());
}
}
//微信支付
public static void pay(WeChat wc) {
wc.payOnline();
}
//支付宝支付
public static void pay(AliPay ap) {
ap.payOnline();
}
//招商银行支付
public static void pay(BankCard bc) {
bc.payOnline();
}
}
看了上面的代码,大家肯定会觉得冗余哈,大家都学过面向对象的多态特性,可以将测试类中的方法进行简化,pay方法定义形参为Mtwm(美团外卖)这个接口,等我们调用时传入对应的实现类即可。于是,代码可以简化为如下:
public class Test {
public static void main(String[] args) {
//定义一个字符串,用来模拟前台的支付方式:
String str = "微信";
if ("微信".equals(str)) {
// 微信支付:
pay(new WeChat());
}
if ("支付宝".equals(str)) {
//支付宝支付:
pay(new AliPay());
}
if ("招商银行".equals(str)) {
pay(new BankCard());
}
}
//支付
public static void pay(Mtwm m) {
m.payOnline();
}
}
多态确实可以提高代码的扩展性,但是:扩展性没有达到最好。
怎么没有达到最好呐:上面的分支判断,还是需要手动的删除或者添加,当接入中国银行/广州银行/花旗银行等的时候,是需要修改这个测试代码类的。
那更好的解决办法:反射机制 利用反射实现上述功能:
public class Test {
public static void main(String[] args) {
//定义一个字符串,用来模拟前台的支付方式:
String str = "com.zhaoss.test01.AliPay"; //字符串:实际上:就是微信类的全限定路径
//下面的代码就是利用反射:
Class cls = Class.forName(str);
/*
代码解读,首先根据str所代表的AliPay的全限定类名,去得到AliPay的字节码对象cls(万物皆对象,这里理解为对象更好懂,接下来还会讲解Class这个类)
根据cls字节码对象去获取AliPay这个类的对象实例o,并根据cls获取字节码对象中的方法并执行
*/
Object o = cls.newInstance();
Method method = cls.getMethod("payOnline");
method.invoke(o);
}
//支付
public static void pay(Mtwm m) {
m.payOnline();
}
这样修改之后,程序变得更加的简洁,并且以后外部又有谁要实现这个接口,这个程序都不必再进行改动,实现了解耦。
2.通过概念再体会反射
反射概念:
JAVA反射机制是在运行状态
中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象, 都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
帮助理解:
在编译后产生字节码文件的时候,类加载器子系统通过二进制字节流,负责从文件系统加载class文件。 在执行程序(java.exe)时候,将字节码文件读入JVM中--->这个过程叫做类的加载。然后在内存中对应创建一个java.lang.Class对象-->这个对象会被放入字节码信息中,这个Class对象,就对应加载那个字节码信息,这个对象将被作为程序访问方法区中的这个类的各种数据的外部接口。 所以:我们可以通过这个对象看到类的结构,这个对象就好像是一面镜子,透过镜子看到类的各种信息,我们形象的称之为反射 这种“看透”class的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。
疑惑点,需要解决:每个类被加载的时候,都只加载一次,创建该类对应的Class对象,这个对象会被放进字节码信息中,即每个类都有对应的字节码信息,而每个字节码信息中又存放了该类的Class对象,这个对象是反射得以实现的基础和关键。通过这个对象,获取到该类字节码中的各种信息,构造方法/属性/方法等。其它类加载时都会有一个Class对象创建,那java.lang.Class这个类本身加载的时候,是不是也创建一个自己的Class对象嘞?主要就是加粗这点有疑问,前面说的帮助理解。
补充:
动态语言vs静态语言
1、动态语言
是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以 被引进,已有的函数可以被删除或是其他结构上的变化。通俗点说就是在运 行时代码可以根据某些条件改变自身结构。
主要动态语言: Object-C、 C#、JavaScript、 PHP、 Python、 Erlang 。
2、静态语言
与动态语言相对应的,运行时结构不可变的语言就是静态语言。如Java、C、 C++。
所以Java不是动态语言,但Java可以称之为“准动态语言”。即Java有一定的动 态性,我们可以利用反射机制、字节码操作获得类似动态语言的特性。 Java的动态性让编程的时候更加灵活!
3.Class类的理解--万物皆对象
通过Class类,可以得到具体的Class类的对象,字节码信息对象。得到这个后就可以获取剩下的属性方法构造方法等,既而创建该类的对象。
4.获取字节码信息的4种形式
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
//案例:以Person的字节码信息为案例 /
//方式1:通过getClass() 方法获取
Person p = new Person();
Class c1 = p.getClass();
System.out.println(c1);
//方式2:通过内置class属性:
Class c2 = Person.class;
System.out.println(c2);
System.out.println(c1 == c2);
//注意:方式1和方式2 不常用 /
//方式3:--》用的最多:调用Class类提供的静态方法forName
Class c3 = Class.forName("com.zhaoss.test02.Person");
//方式4:利用类的加载器(了解技能点)
ClassLoader loader = Test.class.getClassLoader();
Class c4 = loader.loadClass("com.zhaoss.test02.Person");
}
}
5.可以作为Class这个类的类实例的种类
Class类的具体的实例:
(1)类:外部类,内部类
(2)接口
(3)注解
(4)数组
(5)基本数据类型
(6)void
/**
* @author wangcc
* @create 2020-11-04 1:30
**/
public class Demo {
public static void main(String[] args) {
Class c1 = Person.class;
Class c2 = Comparable.class;
Class c3 = Override.class;
int[] arr1 = {1, 2, 3};
Class c4 = arr1.getClass();
int[] arr2 = {5, 6, 7};
Class c5 = arr2.getClass();
System.out.println(c4 == c5);//结果:true .同一个维度,同一个元素类型,得到的字节码就是同一个
Class c6 = int.class;
Class c7 = void.class;
}
}
学习了这篇文章基本上就差不多了,接下来一篇就是反射的api调用,根据反射获取属性,方法,构造方法,各种修饰符的,创建对象,为属性赋值等操作。明天再写,太晚了今天。
Java反射开窍--1的更多相关文章
- Java反射应用--2
Java反射开窍第一篇 明天再写
- 第28章 java反射机制
java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...
- Java反射机制
Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射: 静态编译:在编译时确定类型,绑定对象,即通过 ...
- java反射(基础了解)
package cn.itcast_01; /** *Person类 */ public class Person { /** 姓名 */ private String name; ...
- java基础知识(十一)java反射机制(上)
java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...
- java基础知识(十一)java反射机制(下)
1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...
- java反射学习之二万能EXCEL导出
一.EXCEL导出的实现过程 假设有一个对象的集合,现在需要将此集合内的所有对象导出到EXCEL中,对象有N个属性:那么我们实现的方式是这样的: 循环这个集合,在循环集合中某个对象的所有属性,将这个对 ...
- java反射学习之一反射机制概述
一.反射机制背景概述 1.反射(reflection)是java被视为动态语言的一个关键性质 2.反射机制指的是程序在运行时能获取任何类的内部所有信息 二.反射机制实现功能概述 1.只要给定类的全名, ...
- java反射 之 反射基础
一.反射 反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 ...
随机推荐
- 2021升级版微服务教程3—Eureka完全使用指南
2021升级版SpringCloud教程从入门到实战精通「H版&alibaba&链路追踪&日志&事务&锁」 默认文件1610014380163 教程全目录「含视 ...
- python3 处理列表嵌套字典去重
def list_dict(dictlist): def function(date): return date['ip'] dictlist_new = [] for list_dict in di ...
- .NET 云原生架构师训练营(模块二 基础巩固 RabbitMQ Masstransit 介绍)--学习笔记
2.6.6 RabbitMQ -- Masstransit 介绍 Masstransit 是什么 Quickstart 消息 Message Masstransit 是什么 Masstransit 是 ...
- 【SpringBoot1.x】SpringBoot1.x 日志
SpringBoot1.x 日志 日志框架 市面上有很多日志框架,一个日志框架一般包括抽象层和实现. SpringBoot,它的底层是 Spring,而 Spring 框架默认是用 JCL(java. ...
- 【Flutter】功能型组件之颜色和主题
前言 Color类中颜色以一个int值保存,显示器颜色是由红.绿.蓝三基色组成,每种颜色占8比特,存储结构如下: Bit(位) 颜色 0-7 蓝色 8-15 绿色 16-23 红色 24-31 Alp ...
- XSS-labs通关挑战(xss challenge)
XSS-labs通关挑战(xss challenge) 0x00 xss-labs 最近在看xss,今天也就来做一下xss-labs通过挑战.找了好久的源码,终于被我给找到了,因为在GitHub上 ...
- python学习笔记 | 猜拳游戏
''' @author: 人人都爱小雀斑 @time: 2020/3/6 18:52 @desc: 实验结果心得: 1.难点主要在判断谁输谁赢 2.挺好的 ''' import random d={1 ...
- 系统吞吐量与QPS/TPS
QPS/TPS QPS:Queries Per Second意思是"每秒查询率",是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准. ...
- 摆脱 996——GitHub 热点速览 v.21.03
作者:HelloGitHub-小鱼干 Twitter 有位程序员总结了本周的 GitHub 中文程序员的看点:国内程序员日常--考公务员.996.抢茅台.刷算法.整健康码.在本期热点速览里,小鱼干收录 ...
- Kioptix Level 1
1. 简介 Vulnhub是一个提供各种漏洞环境的靶场平台. 个人学习目的:1,方便学习更多类型漏洞.2,为OSCP做打基础. 下载链接 https://www.vulnhub.com/entry/k ...