获取Class Type的三种方式
获取
Class c1 = Foo.class;
Class c2 = foo.getClass();
c1 == c2 -> true 类对象唯一
Class c3 = Class.forName("com.xxx.Foo");
推荐使用该方式,最快,但会抛异常,要try-catch
使用
1
| Foo foo = (Foo)c1.newInstance();
|
动态加载类
使用new创建对象,是静态加载类,在编译时刻就需要加载所有可能用到的类。 如果项目中大部分类暂时用不到(比如用于解决特例情况),或者为了避免因一个(模块)类的失效导致整个系统的不可用,我们可以使用动态(运行时)加载类。
如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Excel implements OfficeAble { public void start() { System.out.println("Excel starting...") } } class Word implements OfficeAble { public void start() { System.out.println("Word starting...") } } class Office { public static void main(String[] args) { try { Class class = Class.forName(args[0]); OfficeAble oa = (OfficeAble)class.newInstance(); oa.start(); } catch (Exception e) { e.printStackTrace(); } } }
|
编译好发布以后,后期软件更新,新的模块(如ppt)只需要实现OfficeAble接口即可。
获取Class Type信息
我们可以通过以下代码简单地获取一个类的成员函数,成员变量和构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| public class ClassUtil {
public static void printClassMethodMessage(Object obj){ Class c = obj.getClass(); System.out.println("类的名称是:"+c.getName());
Method[] ms = c.getMethods(); for(int i = 0; i < ms.length;i++){ Class returnType = ms[i].getReturnType(); System.out.print(returnType.getName()+" "); System.out.print(ms[i].getName()+"("); Class[] paramTypes = ms[i].getParameterTypes(); for (Class class1 : paramTypes) { System.out.print(class1.getName()+","); } System.out.println(")"); } }
public static void printFieldMessage(Object obj) { Class c = obj.getClass();
Field[] fs = c.getDeclaredFields(); for (Field field : fs) { Class fieldType = field.getType(); String typeName = fieldType.getName(); String fieldName = field.getName(); System.out.println(typeName+" "+fieldName); } }
public static void printConMessage(Object obj){ Class c = obj.getClass();
Constructor[] cs = c.getDeclaredConstructors(); for (Constructor constructor : cs) { System.out.print(constructor.getName()+"("); Class[] paramTypes = constructor.getParameterTypes(); for (Class class1 : paramTypes) { System.out.print(class1.getName()+","); } System.out.println(")"); } } }
|
方法的反射
方法名称+参数列表 确定一个方法
通过method.invoke();
实现反射调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public class MethodDemo { public static void main(String[] args) { A a1 = new A(); Class c = a1.getClass();
try { Method m = c.getMethod("print", int.class,int.class); Object o = m.invoke(a1, 10,20); System.out.println("=================="); Method m1 = c.getMethod("print",String.class,String.class); o = m1.invoke(a1, "hello","WORLD"); System.out.println("==================="); Method m2 = c.getMethod("print"); m2.invoke(a1); } catch (Exception e) { e.printStackTrace(); } } } class A{ public void print(){ System.out.println("helloworld"); } public void print(int a,int b){ System.out.println(a+b); } public void print(String a,String b){ System.out.println(a.toUpperCase()+","+b.toLowerCase()); } }
|
帮助理解泛型的本质
Java中集合的泛型,定义的模板是防止错误输入的,只在编译阶段有效,编译阶段以后就无效了,我们可以通过方法的反射来操作,绕过泛型模板的限制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class MethodDemo { public static void main(String[] args) { ArrayList list = new ArrayList(); ArrayList<String> list1 = new ArrayList<String>(); list1.add("hello"); Class c1 = list.getClass(); Class c2 = list1.getClass(); System.out.println(c1 == c2); try { Method m = c2.getMethod("add", Object.class); m.invoke(list1, 20); System.out.println(list1.size()); System.out.println(list1);
} catch (Exception e) { e.printStackTrace(); } } }
|