饥人谷技术博客

类型与反射

2020-07-01  本文已影响0人  写代码的海怪

对于类型与反射,我的理解是在运行时可以动态地对类进行一些操作。

比如:XXX x = new XXX() 这个 XXX 我是可以外部输入的,输入"Cat" 的时候就是 Cat x = new Cat(),输入"Dog" 的时候,就是 Dog x = new Dog()

但是这在一般的编程是很难这样动态地做到的,因此需要反射。

运行 Java 文件的过程

Java 文件的运行过程是这样的:

xxx.java -> 编译 -> xxx.class -> 运行

通俗来讲,每个类型要变成一份“说明书”(xxx.class),然后在 new XXX() 的时候是根据这份“说明书”来创建对象的。

这不禁让我们想到:能不能在运行的时候去修改这份说明书,比如加入变量,修改里面方法等,然后再根据这份“修改过的说明书”去 new 对象呢?

ClassLoader

为了去更深入想上面的问题,先来看看这个玩意:ClassLoader,它负责从外部加载一个类,也就是我们的 xxx.java -> 编译 -> xxx.class 这一步。这个很容易理解,就相当于编译器嘛。

不过它也有下面特点:

上面的这些特点不禁让我们想到可以“动态地”修改“说明书”了。

反射

反射就是可以在运行的时候去修改这份说明书的,然后我们可以调用 ClassLoader 去编译其实就是我们所说的动态XXXX。有了反射,我们可以

动态创建一个对象

String className = args[0];

Class c = Class.forName(className);

Object obj = c.getConstructor().newInstance();

动态调用一个方法

Cat cat = new Cat();

cat.getClass().getMethod(args[0]).invoke();

动态获取一个属性

Cat cat = new Cat();

cat.getClass().getField(args[0]).get(cat)

双亲委派模型

看名字就看不懂,意思其实很简单,如果一个类如 String 已经声明,然后你再别的地方再声明 String,那你的 String 并不会被加载。伪代码如下:

if (java.lang 包里有没有 String 类被加载?) {
  不管了,直接结束
} else {
  load(自己写的包的 String 类)
}
上一篇 下一篇

猜你喜欢

热点阅读