概述
今天重新学习了一下反射,比刚开始学习的时候轻松了许多。所以如果你是第一次学习反射,不要害怕,就当是自己预习了。等你学习第二遍的时候,你肯定就会轻而易举的理解当时死活看不懂的知识了。
既然说到了反射,就先说一说我们普通的创建对象的过程吧。
假如有一个类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()方法呢???
本人初学者,请大神赐教
最后
以上就是有魅力草丛为你收集整理的JAVA重要知识!反射!的全部内容,希望文章能够帮你解决JAVA重要知识!反射!所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复