韩顺平Java自学笔记 反射

一。反射入门案例

目录

一。反射入门案例

 二。反射的机制

1.反射的原理

2.反射相关的类

3.反射的优点和缺点

三。Class类详解

1.Class类的特征 

2.Class的常用方法

 3.获取Class对象的六种方法

4.那些类型有Class对象

 四。类加载

1.动态加载和静态加载

2.类的加载流程

3.获取类的结构信息

4.反射爆破

 五。课后的作业

1.课后作业1

2.课后作业2


提出一个问题,如何修改外部的配置文件,来操控java内部代码的执行逻辑。

反射类

ReflectionQuestion

package com.hspaidu.reflection.qusetion;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectionQuestion {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//        使用properties类可以引入外部文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\re.properties"));
//        获得class的全部路径
        String classfullpath = properties.get("classfullpath").toString();
//        得到对象的方法
        String method = properties.get("method").toString();
        System.out.println("method = "+method);
        System.out.println("classfullpath = " + classfullpath);
//      返回了一个class类的类对象
        Class cls = Class.forName(classfullpath);
//      通过cls得到对象的实例  可以不用强转也是cat类型
        Object o = cls.newInstance();
        System.out.println("o的运行类型 = "+o.getClass());
//        得到类当中cls的方法的对象  方法也是对象
        Method method1 = cls.getMethod(method);
//        通过方法的对象来调用类实例当中的方法
        method1.invoke(o); // 方法.invoke(对象)
    }
}

运行结果

method = hi
classfullpath = com.hspaidu.Cat
o的运行类型 = class com.hspaidu.Cat
Hi  招财猫 

 被操作的类

Cat

package com.hspaidu;

public class Cat {
    private String name = "招财猫";
    public void hi(){
        System.out.println("Hi  "+name);
    }
    public void cry(){
        System.out.println(name+"  在cry");
    }
}

 配置文件

re.properties

classfullpath = com.hspaidu.Cat

method = hi

修改外部文件

classfullpath = com.hspaidu.Cat

method = cry

反射类输出结果

method = cry
classfullpath = com.hspaidu.Cat
o的运行类型 = class com.hspaidu.Cat
招财猫  在cry

 二。反射的机制

1.反射的原理

 Class当中有一些api可以获取类相关的一些信息,比如实例,方法,全类名等。

 所有的类在堆中都有一个复制体,我们可以通过操作这个复制体,来使用这个类。

 原理图

描述:Java程序加载有三个阶段

编译阶段:类有属性和方法,构造器。Cat有hi方法,源代码当中会体现,经过Javac的编译,得到一个Cat.class字节码文件,会有属性,方法,构造器等等,

类的加载阶段:字节码文件会加载到加载区域。将class类对象放到堆当中。字节码文件到堆当中是使用了类加载器的classLoader的,类加载器就体现了反射机制。在底层,已经将放在堆当中对象的属性看成可以操作的对象了。类加载完之后生成对象。该对象知道他是属于那个class对象的。得到class对象之后,就可以对对象进行操作了。

运行阶段:调用Cat cat = new Cat();  cat.hi()  会导致类的加载

2.反射相关的类

代码演示

package com.hspaidu.reflection;

import java.io.FileInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;

public class Reflection01 {
    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString();
        String method = properties.get("method").toString();
        System.out.println("method = "+method);
        System.out.println("classfullpath = " + classfullpath);
//      关于Class对象
        Class cls = Class.forName(classfullpath);
        //并没有进行类型的强转
        Object o = cls.newInstance();
        System.out.println(o.getClass());
//        关于方法
        Method method1 = cls.getMethod(method);
        method1.invoke(o);
//      关于属性
        Field age = cls.getField("age");  //不能得到私有的属性
        System.out.println("年龄"+age.get(o));  //反射反射,反过来的: 成员变量对象.get(对象)

//      关于构造器
        Constructor constructor = cls.getConstructor(); //后边没有参数,返回的是无参的构造器
        System.out.println(constructor);  //没有形参的构造器

        Constructor constructor1 = cls.getConstructor(String.class);  //传入的是String的Class对象
        System.out.println(constructor1); //有形参的构造器
    }
}

 结果

method = cry
classfullpath = com.hspaidu.Cat
class com.hspaidu.Cat
招财猫  在cry
年龄10
public com.hspaidu.Cat()
public com.hspaidu.Cat(java.lang.String)

3.反射的优点和缺点

实例

Reflection02

package com.hspaidu.reflection;

import com.hspaidu.Cat;

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

public class Reflection02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        m1();
        m2();
    }
//    传统的方法来调用hi方法
    public static void m1(){
        Cat cat = new Cat();
        long start = System.currentTimeMillis();
        for (int i=0;i<9000000;i++){
            cat.hi();
        }
        long end = System.currentTimeMillis();
        System.out.println("传统方法调用 hi 耗时 = "+(end-start));
    }

//    反射机制调用
    public static void m2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Class aClass = Class.forName("com.hspaidu.Cat");

        Method hi = aClass.getMethod("hi");
        Object o = aClass.newInstance();
        long start = System.currentTimeMillis();
        for (int i=0;i<9000000;i++){
            hi.invoke(o);
        }
        long end = System.currentTimeMillis();
        System.out.println("反射方法调用 hi 耗时 = "+(end-start));
    }
}

记得把控制台输出语句关了,太耗时间。 

结果

传统方法调用 hi 耗时 = 3
反射方法调用 hi 耗时 = 20 

进行优化

 Reflection02类

package com.hspaidu.reflection;

import com.hspaidu.Cat;

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

public class Reflection02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        m1();
        m2();
        m3();
    }

    //    传统的方法来调用hi方法
    public static void m1() {
        Cat cat = new Cat();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 9000000; i++) {
            cat.hi();
        }
        long end = System.currentTimeMillis();
        System.out.println("传统方法调用 hi 耗时 = " + (end - start));
    }

    //    反射机制调用
    public static void m2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, In
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值