美文网首页
Java-反射

Java-反射

作者: 指尖轻敲 | 来源:发表于2018-12-03 09:39 被阅读4次

Class类的使用

Class类比较特殊,也比较难理解一些,所有类都是它的实例对象。我们用代码来理解一下:

public class ClassDemo {
    public static void main(String[] args){
        Person person = new Person();
    }
}
class Person{}

普通的person是Person类的实例对象,同时Person这个类也是Class类的一个实例对象。当然Class类的实例对象不是new出来,它有三种表示方式,我们来看一下:

第一种:

在知道类名的情况下,调用该类的隐式的静态成员变量class

Class c1 = Person.class;
第二种:

在知道实例对象名的情况下调用对象的getClass()方法。

Class c2 = person.getClass();

可以这么说,c1、c2表示了Person类的类类型

第三种:

通过class类的forName()方法创建,但是需要捕获异常。

Class c3 = null;
try {
    c3 = Class.forName("Person");
}catch (ClassNotFoundException e){
    e.printStackTrace();
}

最后打印可以看到三种方法创建的对象是完全相等的。

System.out.println(c1 == c2 && c2 == c3); //true

我们也完全可以通过类的类类型创建该类的实例对象,调用类类型的newInstance()方法,这里需要做一下类型强转,而且需要捕获两个异常。
先给Person类中添加一个方法,用来测试

class Person{
    public void show(){
        System.out.println("通过类类型也可以创建实例对象鸭");
    }
}

创建出实例对象后调用show()方法,可以看到正常打印。

try {
    Person person1 = (Person) c1.newInstance();
    person1.show();
}catch (InstantiationException e){
    e.printStackTrace();
}catch (IllegalAccessException e){
    e.printStackTrace();
}

Class类还提供了一堆获取成员信息的方法,可以看文档进行了解。(成员方法、变量、构造方法)

动态加载类

之前我们 通过new关键字创建对象属于静态加载,在编译时就要加载所有的类,如果一个有问题就会影响整个程序。那么能不能再调用到的时候再去加载类呢?答案是肯定的,这就是我们要说的动态加载。

不使用动态加载的例子:

if("Man".equals(args[0])){
    Man man = new Man();
}
if("Woman".equals(args[0])){
    Woman woman = new Woman();
}

这里args[0]是一个命令行参数,动态传递进来的,这段代码就要求两个类都得存在,如果有一个不存在即使用不到这个类也会影响整个程序。我们用动态加载可以很好的避免这一点:

try{
    Class c = Class.forName(args[0]);
    Person person = (Person)c.newInstance();
}

这里我们不知道传递进来的是什么类型的,在强转类型时怎么办呢?在创建所有要用到的类(比如Man类实现Person接口)的时候统一实现Person接口即可(泛型)。这样只有用到才会调用此类。

方法反射

先写一个简单的反射了解一下:

class Person{
    public void show(){
        System.out.println("无参方法");
    }
    public void show(int a, int b){
        System.out.println(a+b);
    }
}

Person person = new Person();
Class c = person.getClass();
try {
    // Method method = c.getMethod("show", new Class[]{int.class, int.class});
    Method method = c.getMethod("show", int.class, int.class);
    method.invoke(person, 2, 3);
    Method method1 = c.getMethod("show");
    method1.invoke(person);
}catch (Exception e){
    e.printStackTrace();
}
  1. 先通过前面说过的三种方法获取到类的类类型,这里就是c。

  2. 通过getMethod()方法获取到类的方法,第一个参数是方法名,后面的参数可以是一个参数数组(注释掉部分),也可以直接把参数全部写出来(没有参数可以不写,也可以写空数组)。

  3. 使用方法对象的invoke方法来调用该类的方法,第一个参数是类的实例对象,后面参数和getMethod()写法一样。

  4. 可以看到两个方法都被执行了。

相关文章

  • Java-反射

    Class类的使用 Class类比较特殊,也比较难理解一些,所有类都是它的实例对象。我们用代码来理解一下: 普通的...

  • Java-反射

    参考:https://mp.weixin.qq.com/s/UYqPCmo2vpAibJPh6cupLw 1.定义...

  • Java-反射机制

    简介:通过获取Java编译后产生的字节码(class格式)文件,使用Java的反射机制从而获取得到该类的所有属性、...

  • JAVA-反射技术

    一、技术总结:1、获得类:(1)Class c=Class.forName("classname");(2)Cla...

  • JAVA-反射机制

    Class类类是对象,类是java.lang.Class类的实例对象。任何一个类都有一个隐含的静态成员变量。Cla...

  • Java-反射机制

    思考:在Java运行环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个...

  • Hello Java

    目录 Java-基础(1/6) Java-对象(2/6) Java-核心库类 上(3/6) Java-核心库类下(...

  • Java-反射基本API

    1,什么是反射? 反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。 2...

  • Java-反射-动态代理

    概述 Proxy 提供静态方法来创建动态代理类和动态代理对象; 源码基于 Android-SDK-29 中的 JD...

  • Java-浅析Object类

    Java-浅析Object类 ++2016.7.19++byside @Java-浅析Object类 ======...

网友评论

      本文标题:Java-反射

      本文链接:https://www.haomeiwen.com/subject/tcedcqtx.html