1、Class类
Class的三种表现形式
1 public class ClassDemo{ 2 3 Fu f = new Fu(); 4 Class c1 = f.class; 5 Class c2 = f.getClass(); 6 7 Class c3 = Class.forName("Fu"); 8 } 9 10 class Fu(){ 11 12 }
2、动态加载类
编译器加载类成为静态加载类,运行时加载类称为动态加载类。
静态加载类的实例:
class Office{ public static void main(String[] args) { //new 对象是静态加载类,编译时就需要加载所有的类 if("Word".equals(args[0])) { Word word = new Word(); word.start(); } if("Excel".equals(args[0])) { Excel excel = new Excel(); excel.start(); } } }
动态加载类的实例:
interface OfficeAble { public void start(); }
class Word implements OfficeAble { public void start(){ System.out.println("word start"); } }
class Excel implements OfficeAble { public void start(){ System.out.println("excel start"); } }
class Officebetter{ public static void main(String[] args){ try{ //动态加载类,在运行时刻 Class c = Class.forName(args[0]); //通过类类型创建该类对象 OfficeAble oa = (OfficeAble)c.newInstance(); oa.start(); }catch(Exception e){ e.printStackTrace(); } } }
3、获取类的信息
1 package com.imooc.reflect; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Field; 5 import java.lang.reflect.Method; 6 import java.util.Iterator; 7 8 9 10 /** 11 * @author Administrator 12 * 13 */ 14 /** 15 * @author Administrator 16 * 17 */ 18 public class ClassUtil { 19 /** 20 * 获取类的成员函数信息 21 * @param obj 该对象所属了的信息 22 * */ 23 public static void printClassInfo(Object obj){ 24 //要获取类的信息,首先要获取类的类类型 25 Class c = obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型 26 //获取类的名称 27 System.out.println("类的名称是: "+c.getName()); 28 /* 29 * Method类,方法对象 30 * 一个成员方法就是一个Method对象 31 * getMethods()方法获得的是所有的public的函数,包括继承父类的 32 * getDeclaredMethods获取的是所有该类自己声明的方法 33 * */ 34 Method[] ms = c.getMethods(); //c.getDeclaredMethods(); 35 for(int i=0;i<ms.length;i++){ 36 37 //得到返回值类型的类类型 38 Class returnType = ms[i].getReturnType(); 39 System.out.print(returnType.getName()+" "); 40 //得到方法的名称 41 System.out.print(ms[i].getName()+"("); 42 //获取参数类型-->得到的是参数列表的类型的类类型 43 Class[] paramTypes = ms[i].getParameterTypes(); 44 for(Class cl : paramTypes){ 45 System.out.print(cl.getName()+","); 46 } 47 System.out.println(")"); 48 } 49 } 50 /** 51 * 获取类的成员变量的信息 52 * */ 53 public static void printFieldInfo(Object obj) { 54 Class c = obj.getClass(); 55 /** 56 * 成员变量也是对象 57 * java.lang.reflect.Field 58 * Field封装了关于成员变量的操作 59 * getFields获取的是所有的public成员变量信息 60 * getDeclaredFields获取所有自己声明的成员变量信息 61 * */ 62 //Field[] fs = c.getFields(); 63 Field[] fs = c.getDeclaredFields(); 64 for(Field f : fs) 65 { 66 //得到成员变量的类类型 -->名字 67 Class fieldType = f.getType(); 68 String typeName = fieldType.getName(); 69 //获得成员变量的名字 70 String fieldName = f.getName(); 71 System.out.println(typeName+" : "+fieldName); 72 } 73 } 74 75 /** 76 * 打印对象的构造函数信息 77 * @param obj 78 */ 79 public static void printConstructerInfo(Object obj){ 80 Class c = obj.getClass(); 81 /* 82 * 构造函数也是对象 83 * java.lang.Construction中封装了构造函数的信息 84 * getConstructors获得所有的public的构造函数 85 * getDeclaredConstructors得到所有的构造函数 86 * */ 87 // Constructor[] cs = c.getConstructors(); 88 Constructor[] cs = c.getDeclaredConstructors(); 89 for (Constructor constructor : cs) { 90 System.out.print(constructor.getName()+"("); 91 //获取构造函数的参数列表-->参数列表的类类型 92 Class[] paramType = constructor.getParameterTypes(); 93 for (Class class1 : paramType) { 94 System.out.print(class1.getName()+","); 95 } 96 System.out.println(")"); 97 } 98 } 99 }
4、方法的反射操作
1 package com.imooc.reflect; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 6 public class MethodDemo1 { 7 public static void main(String[] args){ 8 //要获取print(int,int)方法 9 10 // 1、获取类的类类型 11 12 A a = new A(); 13 Class c = a.getClass(); 14 15 try { 16 /* 17 * 2、获取方法 18 * getMethod(name,parameterType)获取public方法 19 * getDeclaredMethod 自己声明的方法 20 * */ 21 //Method m = c.getDeclaredMethod("print", new Class[]{int.class,int.class}); 22 Method m = c.getMethod("print", int.class,int.class); 23 Method m1 = c.getMethod("print", String.class,String.class); 24 //a.print(10,20); 反射操作为m对象来进行方法调用 25 //有返回值会返回具体的值 26 Object o = m.invoke(a,new Object[]{10,20}); 27 } catch (Exception e) { 28 e.printStackTrace(); 29 } 30 } 31 } 32 33 class A{ 34 public void print(int a,int b){ 35 System.out.println(a+b); 36 } 37 public void print(String a, String b){ 38 System.out.println(a.toUpperCase()+b.toLowerCase()); 39 } 40 }
5、泛型的本质
1 package com.imooc.reflect; 2 3 import java.lang.reflect.Method; 4 import java.util.ArrayList; 5 6 public class MethodDemo2 { 7 public static void main(String[] args) { 8 ArrayList list = new ArrayList(); 9 10 ArrayList<String> list1 = new ArrayList<String>(); 11 list1.add("hello"); 12 //list1.add(20);错误的 13 Class c1 = list.getClass(); 14 Class c2 = list1.getClass(); 15 System.out.println(c1 == c2); 16 //反射的操作都是编译之后的操作 17 18 /* 19 * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的 20 * Java中集合的泛型,是防止错误输入的,只在编译阶段有效, 21 * 绕过编译就无效了 22 * 验证:我们可以通过方法的反射来操作,绕过编译 23 */ 24 try { 25 Method m = c2.getMethod("add", Object.class); 26 m.invoke(list1, 20);//绕过编译操作就绕过了泛型 27 System.out.println(list1.size()); 28 System.out.println(list1); 29 /*for (String string : list1) { 30 System.out.println(string); 31 }*///现在不能这样遍历 32 } catch (Exception e) { 33 e.printStackTrace(); 34 } 35 } 36 37 }