JAVA重要知识!反射!

来源:互联网 发布:换手率软件使用说明 编辑:程序博客网 时间:2024/06/02 03:11
今天重新学习了一下反射,比刚开始学习的时候轻松了许多。所以如果你是第一次学习反射,不要害怕,就当是自己预习了。等你学习第二遍的时候,你肯定就会轻而易举的理解当时死活看不懂的知识了。

既然说到了反射,就先说一说我们普通的创建对象的过程吧。
假如有一个类Person

Person p = new Person();

这一步创建对象的过程是分了三小步!
1.生命变量p (变量p存放在栈内存中)
2.开始new Person(),位对象分配内存空间。(在堆内存中分配)
3.指针移位。将堆内存中的地址,分配给栈p,让p指向内存。


上面说了我们普通创建对象的过程。下面来看一看这个反射到底是个什么玩意儿!

new对象 : 是先有类,然后通过类去创建对象。反射 : 反射是知道了类的全路径,然后通过类的全路径去获得类的实例

我们常用的new对象可以理解为辛勤劳作的劳苦大众!
而反射,则可以理解为空手套白狼的坏蛋,知道了类的全路径,就把能搞到一个对象

所以,反射其实是破坏了面向对象的封装的!

但是呢!反射的作用确实很大。下面我们来一起看一下。

首先理解一下什么是Class类。
注意:此处的Class中首字母是大写的,指的是一个类,而不是我们经常说的class(关键字)!

Class类的作用:Class类,是类的描述符。它比较特殊:没有公有构造函数,所以不能new对象。


下面来看看反射是怎么通过类的全路径创建对象的。

public class Test {    public static void main(String[] args) throws Exception{        Class<Demo> clazz =Class.forName("com.myproject.Demo");        Demo demo = clazz.newInstance();    }}

反射就是Class类通过Person的描述符创建一个Class类的对象。然后通过calzz调用newInstance()方法来创建Person对象的实例。


此处先说明一个反射牛逼的功能:
当我们的一个构造器是被private修饰的时候,我们仍然可以调用这个构造函数。只要给这个构造器设置一个可访问的属性即可!

例如Demo的构造函数是私有的:如下:

public class Demo {    private Demo(){        System.out.println("这是默认的构造函数");    }}

获取Demo私有的构造函数,来创建对象

   @Test    public void test() throws Exception{        Class<Demo> clazz = Demo.class;        Constructor constroctor = clazz.getDeclaredConstructor();        //这一句话起到了重要作用!!!!        constroctor.setAccessible(true);        constroctor.newInstance();    }

只要将构造器的这个方法设置为true即可访问私有的构造函数。

然而此时的构造函数仍然是私有的,只不过该方法只是将方法区中的状态更改了,跟字节码没有关系。



上面说的是反射创建对象,下面来贴出反射调用方法的代码:

显示Demo类的代码:

public class Demo {    public Demo(){        System.out.println("这是默认的构造函数");    }    public void fun(String name){        System.out.println("这是普通方法"+name);    }}

然后是反射类的代码:

public class ReflectDemo {    @Test    public void test() throws Exception{        Class<Demo> clazz = Demo.class;        Demo demo = clazz.newInstance();        Method method = clazz.getDeclaredMethod("fun",String.class);        method.invoke(demo,"haha");    }}

通过反射调用方法,是通过先获取方法的对象,然后通过invoke方法来调用。

但是有一点我们好奇,既然invoke方法中传入了demo对象,为什么不直接使用demo对象直接调用fun()方法呢???

本人初学者,请大神赐教

原创粉丝点击