Java Reflect 反射笔记

    xiaoxiao2021-03-25  81

    Java Reflect 反射笔记 * 1)class类


    类 是java.lang.Class类的实例对象

    package com.rocky.reflect; public class ClassDemo1 { public static void main(String[] args) { // Foo的实例对象如何表示? Foo foo1 = new Foo(); // Foo这个类,也是Class类的实例对象,如何表示? // 任何一个类都是Class的实例对象,这个实例对象有三种表示方式 // 第一种。。实际在告诉我们任何一个类都有一个隐含的静态成员变量class Class c1 = Foo.class; // 第二种。。。该类的对象通过getClasss方法 Class c2 = foo1.getClass(); /* * 官网c1.c2表示了Foo类的类类型class type 万事万物皆对象 类也是对象,是Class类的实例对象 * 这个对象我们称为该类的类类型 */ System.out.println(c1 == c2); // 结果 true 不管从c1 或者 c2代表了Foo类的类类型,一个类只可能是Class类的一个实例对象 // 第三种表达方式 Class c3 = null; try { c3 = Class.forName("com.rocky.reflect.Foo"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println(c2 == c3); // true // 我们可以通过类的类类型创建该类的对象实例 // 即我们可以通过从c1,或c2,或c3创建Foo 类的实例对象 try { Foo foo = (Foo) c1.newInstance(); // 需要有无参数的构造方法! foo.print(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } class Foo { void print() { System.out.println("hello......"); } } 动态加载类

    Class.forName(“类的全称”) * 不仅表示了类的类类型,还代表了动态加载类 * 请区分 编译,运行 * 编译时加载类是静态加载类;运行时加载类是动态加载类

    // new 创建对象 是静态加载类,在写编译时刻就需要 加载所有的可能用到的类 //通过动态加载类,在运行时刻,编译不会报错 //通过类类型,创建该类的对象 // 不同类可以实现统一标准的借口实现 class Office{ public static void main (String[] args){ if ("Word".equals(args[0])) { Word w = new Word(); w.start(); } if ("Excel".equals(args[0])) { Excel e = new Excel(); e.start(); } } } class Word{ public static void start(){ System.out.println("Word....start...."); } } class Excel{ public static 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(); } } } 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....”); } }

    说明:通过动态加载和接口的使用可以增强代码的维护性。后期新增功能,OfficeBetter不需要重新编译。 * Class 常见API

    package com.rocky.reflect; public class ClassDemo2 { public static void main(String[] args) { Class c1 = int.class;// int 的类类型 Class c2 = String.class; // String 的类类型 (String类的字节码。。。 Class c3 = double.class; Class c4 = Double.class; Class c5 = void.class; System.out.println(c1.getName()); System.out.println(c2.getName()); System.out.println(c2.getSimpleName()); //不包含包名的类的名称 System.out.println(c5.getName()); }

    } * Java获取方法信息

    package com.rocky.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class ClassUtil { // 获取类的信息 public static void printClassMessage(Object obj){ //要获取类的信息 首先要获取类的类类型 Class c = obj.getClass(); //传递的是哪个子类的对象,c就是该子类的类类型 System.out.println("类的名称是: " + c.getName()+" "); /* * 一个成员方法就是一个Method 对象 * getMthods()方法获取的是所有public的函数,包括父类继承来的 * getDelaredMethods()获取的是所有该类自己声明的方法,不问访问权限 */ Method[] ms = c.getMethods(); //c.getDeclaredMethods() for(int i = 0; i < ms.length; i++){ // 得到方法的返回值类型的类类型 Class returnType = ms[i].getReturnType(); System.out.print(returnType.getName()+" "); System.out.print(" ( "); //得到方法的名称 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(); // 第一步,或区该类的类类型 /* * 成员变量也是对象 * java.lang.reflect.Field * Field类封装了关于成员变量的操作 * getField() 方法获取的是所有public 的成员变量的信息 * getDeclaredFields() 获取的是该类自己声明的成员变量信息 */ // Field[] fs = c.getFields(); 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.getConstructors(); //c.getDeclaredConstrucors(); 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(")"); } } } package com.rocky.reflect; public class ClassDemo3 { public static void main(String[] args) { // TODO Auto-generated method stub String s = "hello"; ClassUtil.printClassMessage(s); Integer n1 = 1; ClassUtil.printClassMessage(n1); } } package com.rocky.reflect; public class ClassDemo4 { public static void main(String[] args) { ClassUtil.printConMessage("hello"); System.out.println("_________"); ClassUtil.printConMessage(new Integer(3)); } }

    java.lang.String([B,int,int,) java.lang.String([B,java.nio.charset.Charset,) java.lang.String([B,java.lang.String,) java.lang.String([B,int,int,java.nio.charset.Charset,) java.lang.String([B,int,int,java.lang.String,) java.lang.String(java.lang.StringBuilder,) ………………………….


    java.lang.Integer(int,) java.lang.Integer(java.lang.String,)

    package com.rocky.reflect; import java.lang.reflect.Method; public class MethodDemo1 { public static void main(String[] args) { // 要获取print(int,int)方法,1,获取一个方法就是获取类的i信息, // 获取类的信息,首先要获取该类的类类型 A a1 = new A(); Class c = a1.getClass(); //2,获取方法 由名称和参数列表决定 //getMethod获取的是public的方法 //getDelcaredMethod自己声明的方法 try { Method m = c.getMethod("print", int.class,int.class); // Method m = c.getMethod("print", new Class[]{int.class,int.class}); // 方法的反射操作 // a1.print(10,20); 方法的反射操作是用m对象调用a1.print()方法 // Object o = m.invoke(a1, new Object[]{}); Object o = m.invoke(a1, 10,20); System.out.println(o); System.out.println("________________________"); Method m1 = c.getMethod("print", String.class,String.class); //方法如果没有返回值返回null,有返回值返回具体的返回值 Object o1 = m1.invoke(a1, "Hello","World"); System.out.println(o1); } catch (Exception e) { e.printStackTrace(); } } } class A{ 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()); } }

    30 null


    HELLOworld null

    package com.rocky.reflect; import java.lang.reflect.Method; import java.util.ArrayList; public class Methodemo4 { public static void main(String[] args) { ArrayList list = new ArrayList(); ArrayList<String> list1 = new ArrayList<String>(); list1.add("Hello"); // list1.add(20); 报错,范型防止错误输入 Class c1 = list.getClass(); Class c2 = list1.getClass(); System.out.println(c1 == c2); // true /* * 反射的操作都是编译之后的操作,即运行时刻 *c1 == c2 为true说明:编译之后集合的范型是去范型化的 *JAVA中集合的范型,是防止错误输入的,只在编译时刻有效、 *绕过编译就无效了 */ // 验证:我们可以通过方法的反射来操作,绕过编译 try { Method m = c2.getMethod("add", Object.class); m.invoke(list1, 20); //这样编译操作就绕过了范型 System.out.println(list1.size()); System.out.println(list1); // for (String string : list1) { // System.out.println(string); // } // 不能使用foreach遍历,会出现异常java.lang.ClassCastException } catch (Exception e) { e.printStackTrace(); } } }

    true 2 [Hello, 20]


    转载请注明原文地址: https://ju.6miu.com/read-26509.html

    最新回复(0)