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的更多相关文章

  1. Java反射应用--2

    Java反射开窍第一篇 明天再写

  2. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  3. Java反射机制

    Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射:     静态编译:在编译时确定类型,绑定对象,即通过 ...

  4. java反射(基础了解)

    package cn.itcast_01; /** *Person类 */ public class Person {    /** 姓名 */    private String name;     ...

  5. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  6. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  7. java反射学习之二万能EXCEL导出

    一.EXCEL导出的实现过程 假设有一个对象的集合,现在需要将此集合内的所有对象导出到EXCEL中,对象有N个属性:那么我们实现的方式是这样的: 循环这个集合,在循环集合中某个对象的所有属性,将这个对 ...

  8. java反射学习之一反射机制概述

    一.反射机制背景概述 1.反射(reflection)是java被视为动态语言的一个关键性质 2.反射机制指的是程序在运行时能获取任何类的内部所有信息 二.反射机制实现功能概述 1.只要给定类的全名, ...

  9. java反射 之 反射基础

    一.反射 反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 ...

随机推荐

  1. introJs用法及在webkit内核浏览器的一个报错

    1.用法 很简单的用法,引入js,引入css,再执行introJs().start();就可以了(备注:introJs会自动去抓取含有data-intro的dom在introJs源码中_introFo ...

  2. SIGGRAPH Asia 2020 电脑动画节(CAF)获奖短片出炉!

    电脑动画节(CAF) 是SIGGRAPH Asia盛会最受瞩目的环节之一.2020年12月15日,SIGGRAPH Asia 2020虚拟线上会议正式宣布了电脑动画节的三部获奖短片:最佳作品奖< ...

  3. 【JavaWeb】EL 表达式

    EL 表达式 简介 EL(Expression Language),即表达式语言. EL 表达式主要是代替 jsp 页面中 表达式脚本 在 jsp 页面中进行数据的输出,因为 EL 表达式在输出数据的 ...

  4. 《计算机组成原理 》& 《计算机网络》& 《数据库》 Roadmap for self-taugh student

    计算机组成原理: UCB的这门课绝对是不错的资源. Great Ideas in Computer Architecture (Machine Structures) B站:https://www.b ...

  5. (十二)random模块

    大致有以下几个函数: print(random.random()) #0到1的浮点型 print(random.randint(1,6)) #1到6的整型 print(random.randrange ...

  6. 攻防世界 - Web(三)

    PHP2: 1.进入页面,进行抓包或后台扫描都没有什么发现,然后网上查一波wp,发现是关于.phps文件,进入index.phps,弹出一段代码,查看源代码, <?php if("ad ...

  7. pod管理调度约束、与健康状态检查

    pod的管理 [root@k8s-master ~]# vim pod.yaml apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: ...

  8. CMU数据库(15-445)Lab0-环境搭建

    0.写在前面 从这篇文章开始.开一个新坑,记录以下自己做cmu数据库实验的过程,同时会分析一下除了要求我们实现的代码之外的实验自带的一些代码.争取能够对实现一个数据库比较了解.也希望能写进简历.让自己 ...

  9. HTML5表格详细教程

    HTML5表格 文章目录 HTML5表格 5.1 定义表格 5.1.1 普通表格.列标题 5.1.2 表格标题 5.1.3 表格行分组.表格列分组 5.2 表格属性 5.2.1 单线表格.分离单元格 ...

  10. (数据科学学习手札104)Python+Dash快速web应用开发——回调交互篇(上)

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...