反射是什么?(概念)
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
反射提供的功能
对任何一个对象,都能够调用这个对象它的任意一个方法和属性。
对于任何一个类,都能够知道它的任意方法属性。
1、在运行时,判断一个对象所属类
2、在运行时,构造任意一个类的对象
3、在运行时,判断一个类所具有的方法和属性
4、在运行时,调用任意一个对象的方法
5、生成动态代理
正文
一、反射入口
牢牢记住面代码,只要使用了反射,这段代码必定是不可少的
Class<?> perClazz = null;
//Class入口
try {
perClazz= Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
二、获取类名(三种方式)
//获取类名(包.类名)
public static void demo01() {
//反射获取类:Class -> 1.Class.forName(全类名) 2.xx.class 3.getClass()
//Class入口
try {
//方法一
Class<?> perClazz = Class.forName("reflect.Person");
System.out.println(perClazz);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//方法二
Class<?> perClazz2 = Person.class;
System.out.println(perClazz2);
//方法三
Person per = new Person();
Class<?> perClazz3 = per.getClass();
System.out.println(perClazz3);
}
三、获取方法名
这里值得注意的是,获取方法可以分为两种:
1、获取所有的公共方法(本类、父类、接口类)
2、获取本类的所有方法(包括 私有 等等)
//获取方法
public static void demo02() {
Class<?> perClazz = null;
//Class入口
try {
perClazz= Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//获取 所有公共方法(1、本类以及父类以及接口类所有方法。2、符合访问修饰符规律)
Method[] methods = perClazz.getMethods();
for(Method method : methods) {
System.out.println(method);
}
System.out.println("=====================");
//获取 当前类的 所有 方法(只能时当前类, 忽略访问修饰符)
Method[] declaredMethods = perClazz.getDeclaredMethods();
for(Method de:declaredMethods) {
System.out.println(de);
}
}
四、获取接口
//获取所有接口
public static void demo03() {
Class<?> perClazz = null;
//Class入口
try {
perClazz= Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Class<?>[] interfaces = perClazz.getInterfaces();
for(Class<?>inter:interfaces) {
System.out.println(inter);
}
}
五、获取父类I(只有一个,单继承多实现)
//获取父类
public static void demo04() {
Class<?> perClazz = null;
//Class入口
try {
perClazz= Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Class<?> superclass = perClazz.getSuperclass();
System.out.println(superclass);
}
六、获取构造方法
//获取构造方法
public static void demo05() {
Class<?> perClazz = null;
//Class入口
try {
perClazz= Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Constructor<?>[] constructors = perClazz.getConstructors();
for(Constructor con:constructors) {
System.out.println(con);
}
}
七、获取属性
属性跟方法一样,有公共属性和私有属性,获取方法和方法一样
//获取属性
public static void demo06() {
Class<?> perClazz = null;
//Class入口
try {
perClazz= Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//获取所有公共属性
Field[] fields = perClazz.getFields();
for(Field fie:fields) {
System.out.println(fie);
}
System.out.println("============================");
//获取当前类所有属性
Field[] declaredFields = perClazz.getDeclaredFields();
for(Field df:declaredFields) {
System.out.println(df);
}
}
八、总结
1、看了这么多,可以发现的是,不管获取什么,反射入口都是一样的。
2、不管Java有什么,反射都能获取得到。
3、获取的方法名都差不多(.getxxx)
(1)field:属性 ------- fields:所有属性
(2)method: 方法 ------ methods:所有方法
(3)constructor : 构造方法 ---------constructors:所有构造方法
(4)superclass : 父类
(5)interface:接口---------interfaces:所有接口