浅析Class类(反射机制原理)

浅析Class类(反射机制原理)

本文总结自网上视频(讲的很详细)

视频链接地址:http://www.imooc.com/learn/199

原文地址:http://blog.csdn.net/zxpmojoker

一.万事万物皆对象

1.静态成员不是对象
静态成员属于类,不属于对象
2.普通数据类型也不属于对象
3.类本身也是对象,是属于java.lang.Class类的实例对象

二.Class对象如何表示

现在有一个类

class Person{
    public void print(){
        System.out.println("Person");
    }
}

Person的实例对象如何表示

Person person = new Person();//person代表Person的实例,可以new出来

Person 这个类也是一个实例对象,是 java.lang.Class 的实例对象,如何表示?

Class类的构造方法是私有的,只有JVM能创建类对象

所以任何一个类都是Class的实例对象,这个实例对象一共有3种表示方式

1.第一种(知道类名): 可以知道任何一个类都有一个隐含的静态成员变量class
Class clazz1 = Person.class;
2.第二种(知道对象名):已经知道该类的对象,通过getClass方法
Class clazz2 = person.getClass();

clazz1 和 clazz2 表示了 person类的类类型(class type)

话句话就是:类也是对象,是Class的实例对象,这个对象我们称为该类的类类型,一个类只能是Class类的一个实例对象.

3.第三种表达方式
Class clazz3 = null;
        clazz3 = Class.forName("com.class.reflect.Person");//写类名全称

这样我们就可以通过类的类类型创建该类的对象实例--->通过clazz1 或 clazz2 或 clazz3 创建Person的实例

Person person = (Person)clazz3.newInstance();//需要有无参构造方法

三.动态加载类

Class.forName("类名全称")

  • 不仅表示了类的类类型,还代表了动态加载类
  • 编译时刻加载类是静态加载类,运行时刻加载类是动态加载类

先来体会下静态加载类

注:这里是在文件里边编写代码

首先创建一个Office.java文件

public class Office {
    public static void main(String[] args) {
        if ("World".equals(args[0])){
            Word w = new Word();
            w.start();
        }
        if ("Excel".equals(args[0])){
            Excle e = new Excel();
            e.start();
        }
    }
}

编译Office.java文件

Office.java:7 错误: 找不到符号
  符号:   类 Word
Office.java:12 错误: 找不到符号
  符号:   类 Excle

会告诉我们Word和Excel都找不到(这是理所当然的,因为我没写Word类和Excel类),但是我们可以想一下,Word和Excel我们一定用的到吗?

再创建出Word类

public class Word {

    public void start(){
        System.out.println("Word");
    }
}

再编译Office.java文件

Office.java:12 错误: 找不到符号
  符号:   类 Excle

依然会有提示找不到Excel类

但是Word存在了,我们想用Word,但是用不了,原因是现在类是静态加载的.

new创建的对象是静态加载类,在编译时刻就需要加载所有可能使用到的类,也就是说如果我们这个程序如果有很多个功能,只要有一个功能有问题,其他的功能全都用不了,而这不是我们期望看到的.这就是静态加载.

而通过动态加载类,我们就可以解决该问题

进行动态加载类

创建OfficeBetter.java文件

public class OfficeBetter {
    public static void main(String[] args) {
        try {
            //动态加载类,在运行时刻
            Class c = Class.forName(args[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

编译OfficeBetter.java文件,不会报错

接下来通过类类型, 创建该类对象:

try {
            //动态加载类,在运行时刻
            Class c = Class.forName(args[0]);
            //通过类类型, 创建该类对象
            (强制类型转换)c.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

强制类型转换这又有一个新的问题,如果强转的是Word,而加载的是Excel怎么办,反之,如果强转的是Excel,加载的是Word又怎么办?

为了能让Word和Excel都能用,就要统一标准,比如都叫OfficeAble:

public interface OfficeAble {
    void start();
}

然后让Word和Excel都实现OfficeAble这个接口就OK了

try {
            //动态加载类,在运行时刻
            Class c = Class.forName(args[0]);
            //通过类类型, 创建该类对象
            OfficeAble officeAble = (OfficeAble) c.newInstance();
            officeAble.start();
        } catch (Exception e) {
            e.printStackTrace();
        }

这样做还有一个好处就是我们以后对这个类不用做任何修改,只需要去修改实现类就行了,比如软件升级,程序员只需运行新添加的功能,不用去修改以前的代码,更不用重新编译.

所有功能性的类一般都使用动态加载而不是静态加载.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值