1 反射
1.1 反射介绍
- 什么是反射:
- 反射可以把它称为动态语言,允许程序在运行期间借助于反射API可以获取类的完整信息。
- 功能:
- 在运行期间可以获取对象的类型
- 可以在运行期间构造对象
- 可以在运行期间可以获取类的完整结构
- 可以在运行期获取指定类的属性和方法及构造器。
- 反射API:
- java.lang.Class 可以获取运行时类的实例
- java.lang.reflect. Field 属性(成员变量)
- java.lang.reflect. Method 方法
- java.lang.reflect. Constructor 构造器
public class TestReflect {
//使用反射
@Test
public void test2() throws Exception {
//运行时类的对象(实例)
Class cla = Student.class;
Student stu = (Student)cla.newInstance(); //创建类的对象
System.out.println(stu);
//属性
Field name = cla.getField("name"); //只能获取public
name.set(stu, "张三");
System.out.println(stu);
//方法
Method m = cla.getMethod("info",String.class,int.class); //只能获取public
m.invoke(stu,"张三", 20 ); //调用
}
//没有用反射
@Test
public void test1() {
Student stu = new Student("",10);
System.out.println(stu);
stu.name="张三";
System.out.println(stu.name);
stu.setSex("男");
stu.info("张三", 20);
}
}
1.2 理解Class类创建Class类的实例
-
Class类:
表示正在运行的Java应用程序中的类和接口
-
原理:
创建一个java类,javac.exe编译.class文件(字节码),此时使java.exe将.class加载(jvm类加载器)到内存中,在内存中的.class文件就是一运行时的类,也可以称为Class类的实例。
-
创建Class类的实例:
- 可以通过运行时类.class来创建. 如:Class c = Student.class; String.class;
- 可以通过类的对象.getClass() 如:Student s = new Student(); Class c = s.getClass();
- 可以通过Class类中的静态方法forName(“”); 如:Class c=Class.forName(“类的全路径”);
- 类加载器获取ClassLoader cl = stu.getClass().getClassLoader();
Class c = cl.loadClass(“com.aura.java2.Student”);
//获取运行时类的实例
@Test
public void test3() throws Exception {
//1
Class c1 = Student.class;
//2
//Student stu = new Student();
Student stu = (Student)c1.newInstance();
Class c2 = stu.getClass();
//3静态方法
Class c3 = Class.forName("com.aura.java2.Student");
System.out.println(c1==c2); //true
System.out.println(c1==c3); //true
}
1.3 根据Class类的实例获取类的完整结构
-
属性
//属性 @Test public void test1() { //获取Class类的实例 Class clazz = Student.class; Field[] fields = clazz.getFields(); //只能public自身和父类 for (Field field : fields) { System.out.println(field.getName()); } System.out.println("==============================="); Field[] declaredFields = clazz.getDeclaredFields();//所有自己但不能获取父类 for (Field f : declaredFields) { //获取修饰符 int m = f.getModifiers(); String str = Modifier.toString(m); System.out.print(str+" "); //类型 Class type = f.getType(); System.out.print(type.getName()+" "); //名称 System.out.println(f.getName()); } }
-
方法
//方法 @Test public void test2() throws Exception { Class clazz = Class.forName("com.aura.java2.Student"); Method[] methods = clazz.getMethods(); //自身和父类public的方法 for (Method m : methods) { System.out.println(m); } System.out.println("=============================="); Method[] methods2 = clazz.getDeclaredMethods(); //自身的所有方法 for (Method m : methods2) { //修饰符 int m1 = m.getModifiers(); String str = Modifier.toString(m1); System.out.print(str+" "); //返回值类型 Class rt = m.getReturnType(); System.out.print(rt.getName()+" "); //方法名 System.out.print(m.getName()); Class[] parameterTypes = m.getParameterTypes(); Parameter[] parameters = m.getParameters(); System.out.print("("); for (int i=0;i<parameterTypes.length;i++) { System.out.print(parameterTypes[i].getName()+" "+parameters[i].getName()); } System.out.print(")"); //异常 Class[] ex = m.getExceptionTypes(); if(ex.length!=0) { System.out.print("throws"); } //输出异常类型 System.out.println(); System.out.println(); } }
-
构造器
//方法 @Test public void test3() throws Exception { Class clazz = Class.forName("com.aura.java2.Student"); Constructor[] c1 = clazz.getConstructors(); //本类公有构造器 for (Constructor constructor : c1) { System.out.println(constructor); } System.out.println("===================================="); Constructor[] c2 = clazz.getDeclaredConstructors(); //本类的所有构造器 for (Constructor constructor : c2) { System.out.println(constructor); } }
-
父类
getSuperClass() //只有一个父类
-
注解
getAnnotations() //所有注解
-
接口
getInterfaces(); //接口有多个
@Test public void test4() throws Exception { Class clazz = Class.forName("com.aura.java2.Student"); clazz.getSuperclass(); //父类 clazz.getAnnotations(); //注解 clazz.getDeclaredAnnotations(); clazz.getInterfaces(); //接口 }
1.4 通过反射获取指定类属性,方法,构造器
-
属性
//设置指定的属性 @Test public void test1() throws Exception { //创建Class类的实例 Class clazz = Student.class; //创建Student类对象 Student stu =(Student)clazz.newInstance(); Field name = clazz.getField("name"); //public name.set(stu, "小明"); System.out.println(stu); //姓名 Field age = clazz.getDeclaredField("age"); //所有的 age.set(stu, 23); System.out.println(stu); //姓名 年龄 //属性 Field sex = clazz.getDeclaredField("sex"); //所有的private sex.setAccessible(true); //设置 权限 private sex.set(stu, "男"); System.out.println(stu); //姓名年龄 性别 }
-
方法
//设置或调用指定的方法 @Test public void test2() throws Exception { //创建Class类的实例 Class clazz = Student.class; //创建Student类对象 Student stu =(Student)clazz.newInstance(); //直接类的无参构造器 //获取指定的方法 Method m = clazz.getMethod("toString"); //public Object result = m.invoke(stu); System.out.println(result); Method m1 =clazz.getDeclaredMethod("show", String.class,int.class); //参数的类型 m1.setAccessible(true); m1.invoke(stu, "小刘",22); //实参 }
-
构造器
//设置或调用指定的构造器 @Test public void test3() throws Exception { //创建Class类的实例 Class clazz = Student.class; //创建Student类对象(调用无参构造 )1 Student stu =(Student)clazz.newInstance(); //直接类的无参构造器 System.out.println(stu); //调用指定的构造器 //无参 2 Constructor c1 = clazz.getConstructor(); Student obj = (Student)c1.newInstance(); System.out.println(obj); System.out.println("=================================="); //有参 Constructor c2 = clazz.getConstructor(String.class,int.class); Student obj2 = (Student)c2.newInstance("李四",25); System.out.println(obj2); //私有权限构造 器 Constructor c3 = clazz.getDeclaredConstructor(String.class,int.class,String.class); c3.setAccessible(true); Student obj3 = (Student)c3.newInstance("赵六",28,"男"); System.out.println(obj3); }