大数据必学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类的理解

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...