1. 获取类的字节码
三种方式
-
Class c = Class.forName("完整类名带包名");
-
Class c = 对象.getClass();
-
Class c = 任何类型.class;
public class ReflectTest01 { public static void main(String[] args) { /* * Class.forName() * 1.静态方法 * 2.方法的参数是一个字符串 * 3.字符串需要一个完整的类名 * 4.完整类名必须带有包名,java.lang包也不能省略 */ try{ //第一种方式 Class c1 = Class.forName("java.lang.String"); //c1代表String.class文件,或者说c1代表String类型 } catch (ClassNotFoundException e) { e.printStackTrace(); } //第二种方式 //java中任何一个类都有一个getClass()方法 Date d = new Date(); Class class1 = d.getClass(); //第三种方式,Java语言中任何一种类型,包括基本数据类型,它都有.class属性 Class c = String.class; } }
2. 通过Class的newInstance()方法来实例化对象
Class的newInstance()方法内部实际上调用了无参数构造方法,必须保证无参构造存在才可以。
public class ReflectTest02 { public static void main(String[] args) { // 这是不使用反射机制,创建对象 User user = new User() // 下面这段代码是以反射机制的方式创建对象。 try { // 通过反射机制,获取Class,通过Class来实例化对象 Class c = Class.forName("com.bjpowernode.java.bean.User"); // c代表User类型。 // newInstance() 这个方法会调用User这个类的无参数构造方法,完成对象的创建。 // 重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的! Object obj = c.newInstance(); System.out.println(obj); // com.bjpowernode.java.bean.User@10f87f48 } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } } }
3. Class.forName()这个方法的执行会导致:类加载。
希望一个类的静态代码块执行,其它代码一律不执行,可以使用:Class.forName("完整类名"); 这个方法的执行会导致类加载,类加载时,静态代码块执行。
4. 反射类当中的Field
public class ReflectTest03 { public static void main(String[] args) throws Exception{ // 获取整个类 Class studentClass = Class.forName("com.bjpowernode.java.bean.Student"); //className = com.bjpowernode.java.bean.Student String className = studentClass.getName(); //simpleName = Student String simpleName = studentClass.getSimpleName(); // 获取类中所有的public修饰的Field Field[] fields = studentClass.getFields(); // 获取所有的Field Field[] fs = studentClass.getDeclaredFields(); // 遍历 for(Field field : fs){ // 获取属性的修饰符列表 int i = field.getModifiers(); // 返回的修饰符是一个数字,每个数字是修饰符的代号!!! // 可以将这个“代号”数字转换成“字符串" String modifierString = Modifier.toString(i); // 获取属性的类型 Class fieldType = field.getType(); String fName = fieldType.getSimpleName(); // 获取属性的名字 field.getName(); } } } public class Student { public int no; private String name; protected int age; boolean sex; }
5. 反射类当中的Method
public class ReflectTest04 { public static void main(String[] args) throws Exception{ // 获取类了 Class userServiceClass = Class.forName("com.bjpowernode.java.service.UserService"); // 获取所有的Method(包括私有的!) Method[] methods = userServiceClass.getDeclaredMethods(); // 遍历Method for(Method method : methods){ // 获取修饰符列表 System.out.println(Modifier.toString(method.getModifiers())); // 获取方法的返回值类型 System.out.println(method.getReturnType().getSimpleName()); // 获取方法名 System.out.println(method.getName()); // 方法的修饰符列表(一个方法的参数可能会有多个。) Class[] parameterTypes = method.getParameterTypes(); for(Class parameterType : parameterTypes){ System.out.println(parameterType.getSimpleName()); } } } }
6. 反射类当中的Constructor
public class ReflectTest05 { public static void main(String[] args) throws Exception{ Class vipClass = Class.forName("java.lang.String"); Constructor[] constructors = vipClass.getDeclaredConstructors(); for(Constructor constructor : constructors){ // 获取修饰符列表 System.out.println(Modifier.toString(constructor.getModifiers())); // 获取构造方法名 System.out.println(vipClass.getSimpleName()); // 获取构造方法的形参类型 Class[] parameterTypes = constructor.getParameterTypes(); for(Class parameterType : parameterTypes){ System.out.println(parameterType.getSimpleName()); } } }
7. 通过反射机制调用构造方法实例化java对象
public class ReflectTest06 { public static void main(String[] args) throws Exception{ Class c = Class.forName("com.bjpowernode.java.bean.Vip"); // 第一步:先获取到这个有参数的构造方法 Constructor con = c.getDeclaredConstructor(int.class, String.class, String.class,boolean.class); // 第二步:调用构造方法new对象 Object newObj = con.newInstance(110, "jackson", "1990-10-11", true); System.out.println(newObj); // 获取无参数构造方法 Constructor con2 = c.getDeclaredConstructor(); Object newObj2 = con2.newInstance(); System.out.println(newObj2); } }
8. 通过反射机制对对象属性赋值和获值
public class ReflectTest07 { public static void main(String[] args) throws Exception{ Class studentClass = Class.forName("com.bjpowernode.java.bean.Student"); // obj就是Student对象。(底层调用无参数构造方法) Object obj = studentClass.newInstance(); // 获取no属性(根据属性的名称来获取Field) Field noFiled = studentClass.getDeclaredField("no"); /* 赋值三要素,缺一不可: 要素1:对象 要素2:属性 要素3:值 对象.属性 = 值; */ noFiled.set(obj, 22222); // 给obj对象的no属性赋值2222 // 读取属性的值 // 两个要素:获取对象的属性的值。对象.属性; System.out.println(noFiled.get(obj)); // 可以访问私有的属性 Field nameField = studentClass.getDeclaredField("name"); // 打破封装(反射机制的缺点:打破封装,可能会给不法分子留下机会!!!) // 这样设置完之后,在外部也是可以访问private的。 nameField.setAccessible(true); // 给name属性赋值 nameField.set(obj, "jackson"); // 获取name属性的值 System.out.println(nameField.get(obj)); } } public class Student { public int no; private String name; protected int age; boolean sex; }
9. 通过反射机制调用一个对象的方法
public class ReflectTest08 { public static void main(String[] args) throws Exception{ /* 调用方法要素分析: 要素1:对象 要素2:方法名 要素3:实参列表 要素4:返回值 返回值 = 对象.方法名(实参列表); */ Class userServiceClass = Class.forName("com.bjpowernode.java.service.UserService"); // 创建对象 Object obj = userServiceClass.newInstance(); // 获取Method Method loginMethod = userServiceClass.getDeclaredMethod("login", String.class, String.class); //调用方法,得到返回值 Object retValue = loginMethod.invoke(obj, "admin", "123123"); System.out.println(retValue); } } public class UserService { public boolean login(String name,String passWord) { if("admin".equals(name) && "123".equals(passWord)) return true; return false; } }
10. 获取这个类的父类和实现了哪些接口
public class ReflectTest09 { public static void main(String[] args) throws Exception{ // String举例 Class stringClass = Class.forName("java.lang.String"); // 获取String的父类 Class superClass = stringClass.getSuperclass(); System.out.println(superClass.getName()); // 获取String类实现的所有接口(一个类可以实现多个接口。) Class[] interfaces = stringClass.getInterfaces(); for(Class in : interfaces){ System.out.println(in.getName()); } } }