大数据必学Java基础八十八:通过案例和概念体会反射的好处

​通过案例和概念体会反射的好处

一、通过案例体会反射的好处

案例:美团外卖 --> 付款 --> 要么用微信支付,要么用支付宝支付

package com.lanson.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("我已经定了外卖,我正在用招商银行信用卡支付");
    }
}

测试类:

package com.lanson.test01;

public class Test {
    public static void main(String[] args) {
        //定义一个字符串,用来模拟前台的支付方式:
        String str = "微信";
        if("微信".equals(str)){//str.equals("微信")---?避免空指针异常
            //微信支付:
            //new WeChat().payOnline();
            pay(new WeChat());
        }

        if("支付宝".equals(str)){
            //支付宝支付:
            //new AliPay().payOnline();
            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();
    }
}

为了提高代码的扩展性 --> 面向对象多态特性

package com.lanson.test01;

public class Test {
    public static void main(String[] args) {
        //定义一个字符串,用来模拟前台的支付方式:
        String str = "微信";
        if("微信".equals(str)){//str.equals("微信")---?避免空指针异常
            //微信支付:
            pay(new WeChat());
        }

        if("支付宝".equals(str)){
            //支付宝支付:
            pay(new AliPay());
        }

        if("招商银行".equals(str)){
            pay(new BankCard());
        }
    }
    //方法形参是接口,具体传入的是接口的实现类的对象---》多态的一种形式
    public static void pay(Mtwm m){
        m.payOnline();
    }
}

多态确实可以提高代码的扩展性,但是扩展性没有达到最好。

怎么没有达到最好,上面的分支,还是需要手动的删除或者添加。

解决办法:反射机制

利用反射实现上述功能

package com.lanson.test01;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo {
    public static void main(String[] args) throws Exception {
        //定义一个字符串,用来模拟前台的支付方式:
        String str = "com.lanson.test01.AliPay";  //字符串:实际上:就是微信类的全限定路径

        //下面的代码就是利用反射:
        Class  cls = Class.forName(str);//cls-->Class类具体的对象--》AliPay字节码信息
        Object o = cls.newInstance();
        Method method = cls.getMethod("payOnline");
        method.invoke(o);
    }
}

二、通过概念再体会反射

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

在编译后产生字节码文件的时候,类加载器子系统通过二进制字节流,负责从文件系统加载class文件。

在执行程序(java.exe)时候,将字节码文件读入JVM中这个过程叫做类的加载。然后在内存中对应创建一个java.lang.Class对象,这个对象会被放入字节码信息中,这个Class对象,就对应加载那个字节码信息,这个对象将被作为程序访问方法区中的这个类的各种数据的外部接口。

所以我们可以通过这个对象看到类的结构,这个对象就好像是一面镜子,透过镜子看到类的各种信息,我们形象的称之为反射。

这种“看透”class的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。

说明:在运行期间,如果我们要产生某个类的对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。

如果没有被加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已被加载到内存,就可以用它来产生该类型的所有对象。

扩展知识:

动态语言vs静态语言

1、动态语言

是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。通俗点说就是在运行时代码可以根据某些条件改变自身结构。

主要动态语言:Object-C、 C#、JavaScript、 PHP、 Python、 Erlang 等

2、静态语言

与动态语言相对应的,运行时结构不可变的语言就是静态语言。

如Java、C、 C++等

所以Java不是动态语言,但Java可以称之为“准动态语言”。即Java有一定的动态性,我们可以利用反射机制、字节码操作获得类似动态语言的特性。 Java的动态性让编程的时候更加灵活。

Class类的理解

原文地址:https://cloud.tencent.com/developer/article/2191622

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340