很多时候,java程序运行中,我们需要在运行时了解类的信息,得到类的实例,并且进而继续得到类的方法,构造函数,权限,变量以及其他信息。这时候我们需要用到一门技术,java反射
反射说白了,就是把我们的一些文件,一些字符串,一些地址上具体的配置信息,能够把他们动态的在运行期实例化,并且我们能够操作这些实例。这就是反射。
以下几段话是我学习Android的思考,只是想学习反射的同学可以直接跳到Class的使用
我学习Android开发的时候,我就在想,我们在layout文件下写的xml布局文件,他是文本文件,是一些配置信息吧。既然万事万物皆对象,那我们的手机界面应该是一个类。
xml布局文件有LinearLayout布局,那是不是有一个LinearLayout类?我在xml布局文件那里配置
android:layout_width="match_parent"
android:layout_height="match_parent"
就能让这个LinearLayout的宽高匹配父布局。那么,如果真的有LinearLayout类的话,会不会有个方法类似于setWidth()让我设置宽高?事实上,有LinearLayout类,提供了setLayoutParams()方法让我们设置布局参数,当然这个方法能设置宽高
那,我们在xml布局文件写的配置信息,在手机界面上能够显示那么丰富的效果,有按钮,有文本,有列表。这是怎么做到的?其实,这就是用到反射,把xml布局文件写的配置信息,动态的实例化,比如Button按钮,TextView文本,在程序运行时刻全都动态实例化。如果没有反射,我们就无法使用(调用)xml布局文件,无法使用到xml布局文件的话,那Android系统怎么加载丰富多彩的界面?
同样的,AndroidManifest文件里配置了很多Activity,都是通过反射来实例化。如果没有反射,也无法使用AndroidManifest里的配置信息。当然也就没有了Android框架了。
Java反射那么重要,我们需要理解了才能够去使用他。那我们就来学习Java反射这门技术
Class类的使用
在面向对象的世界里,万事万物皆对象。
在java的世界里,有两样东西不是面向对象的。基本的数据类型和静态(static)的东西。
比如,int a = 5,他不是面向对象,但是他有包装类(Integer)或者说是封装类,弥补了他。Int a = 5;是直接在栈空间中分配内存。而Integer a = new Integer(5),对象在堆内存中,引用变量a在栈内存。像这样的普通数据类型还好几个,比如boolean与Boolean,char和Character,double与Double等等,他们都不是面向对象
还有是就是java静态的东西,他不属于某个对象,是属于类的
现在,除去以上不是面向对象的。
那么我们写的类,类是不是对象呢?类是谁的对象呢?类是哪个类的对象呢?
我们写的每一个类它也是对象,类是对象,类是java.lang.Class类的实例对象。
我写的一个Student类,他是不是对象,是一个对象。谁的对象?Class类的实例对象
public class Student {
}
注意,我们上面的程序class,c是小写,是关键字。在声明java类时使用。而我们说的java.lang.Class类的C是大写,他是一个类,因为我们定义一个类,类名的首字母是大写的呀。也可以这么理解:
现在有一个类,他的名字就叫Class。java.lang.Class类
Class类能不能new出实例对象呢?这个对象到底如何表示呢?
我们按住ctrl+鼠标左键,追踪Class这个类,发现他的构造方法是私有的,还给出了注释,只有java虚拟机才能创建Class对象,如下所示:
/*
* Constructor. Only the Java Virtual Machine creates Class
* objects.
*/
private Class() {}
既然不能通过调用构造方法,new出实例,那么Class类的实例对象如何表示呢?
接下来我们来学习Class类的使用
我们打开eclipse先新建一个Student类
public class Student {
public void introduce(){
System.out.println("我是一名大三学生");
}
}
在新建一个demo,我们很简单的将Student类的实例对象表示出来
public class ClassDemo {
public static void main(String[] args){
//student1表示Student的实例对象
Student student1 = new Student();
}
}
那么我们说到,Student这个类,也是一个实例对象,是Class类的实例对象
——》紧接上面提到的问题:Class类的实例对象如何表示呢?
任何一个类都是Class类的实例对象(这句话可以心里念三遍)。这个实例对象有三种表示方式:
第一种表示方式 —>通过类名调用静态成员变量class。 类名.class
Class class1 = Student.class;
这实际在告诉我们任何一个类都有一个隐含的静态成员变量class
第二种表示方式 —> 已经知道该类的对象,通过调用getClass方法。object.getClass()
Class class2 =