-
JAVA-Reflect专题
Class类的使用
方法的反射
成员变量的反射
构造函数的反射
Java类加载机制
查看全部 -
万事万物皆对象。
类也是对象,类是java.lang.Class类的实例对象。
Class c1 = Foo.class;
c1是Foo类的类类型(Class Type)
Foo foo1 = (Foo)c1.newInstance();
可以通过类的类类型去创建类的实例对象
前提:该类有无参构造函数,newInstance方法会通过无参构造函数去生成类的实例对象。
查看全部 -
编译时刻加载类是静态加载类,运行时刻加载类是动态加载类
查看全部 -
Foo foo1=new Foo(); Class c1=Foo.class; //任何一个类都有一个隐含的静态成员变量 Class c2=fool.getClass(); Class c3=null; c3=Class.foeName("com.imooc.reflect.Foo");
1.万事万物皆对象,类也是对象,是Class类的实例对象,这个对象我们称为该类的类类型。
2.Fool类的对象就是foo1,Fool类的类类型就是Class的对象
3.c1==c2==c3
4.
//通过类的类类型创建该类的对象实例
Foo foo=(Foo)c1.newInstance();
查看全部 -
//获取类对象的三种形式
//第一种
Student s = new Student();
Class c1 = s.getClass();
//第二种
Class c2 = Student.class();
//第三种
Class c3 = Class.forName("package.Student");
查看全部 -
获取类对象的三种方法
Foo f = new Foo(); // 第一种 Class c1 = f.getClass(); // 第二种 Class c2 = Foo.class; // 第三种(包名+类名) Class c3 = Class.forName("package.Foo");
使用类类型获取该类的对象
Foo f = (Foo)c1.newInstance();
查看全部 -
Java 方法反射的操作
1、如何获取某个方法
方法名称和方法参数列表才能唯一决定某个方法
先获取该类的类类型
A a1 = new A();
Class c = a1.getClass();
再通过类类型获取具体的方法
c.getMethod("print",int.class,int.class);
c.getMethod("print",new Object[]{int.class,int.class});
2、方法反射的操作
Object obj = method.invoke(对象,参数列表);
Object obj = m.invoke(a1,10,20);
Object obj = m.invoke(a1,new Object[]{10,20});
如果该方法没有返回值,则返回null,如果有返回值则返回具体的值
查看全部 -
1、Class类
1) 在面向对象的世界里,万事万物皆对象。(java语言中,静态的成员、普通数据类型除外)
类是不是对象呢?类是(哪个类的对象呢?)谁的对象呢?
类是对象,类是java.lang.Class类的实例对象2 )Class.forName("类的全称")不仅表示了,类的类类型,还代表了动态加载类,请大家区分编译、运行加载类
编译时刻加载类是静态加载类、运行时刻加载类是动态加载类3)基本的数据类型、void关键字都存在类类型
2、方法的反射
1)如何获取某个方法
方法的名称和方法的参数列表才能唯一决定某个方法2)方法反射的操作
method.invoke(对象,参数列表)3)为什么要用方法的反射
指定方法名称调用方法,举个实际应用的案例 ---->通过标准JavaBean的属性名获取其属性值
BeanUtil类import java.lang.reflect.Method; public class BeanUtil { /** * 根据标准javaBean对象的属性名获取其属性值 * * @param obj * @param propertyName * @return */ public static Object getValueByPropertyName(Object obj, String propertyName) { // 1.根据属性名称就可以获取其get方法 String getMethodName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); //2.获取方法对象 Class c = obj.getClass(); try { //get方法都是public的且无参数 Method m= c.getMethod(getMethodName); //3 通过方法的反射操作方法 Object value = m.invoke(obj); return value; } catch (Exception e) { e.printStackTrace(); return null; } } }
ClassUtil
import java.lang.reflect.Constructor; import java.lang.reflect.Field;i mport java.lang.reflect.Method; public class ClassUtil { /** * 打印类的信息,包括类的成员函数、成员变量(只获取成员函数) * @param obj 该对象所属类的信息 */ public static void printClassMethodMessage(Object obj){ //要获取类的信息 首先要获取类的类类型 Class c = obj.getClass();//传递的是哪个子类的对象 c就是该子类的类类型 //获取类的名称 System.out.println("类的名称是:"+c.getName()); /** * Method类,方法对象 * 一个成员方法就是一个Method对象 * getMethods()方法获取的是所有的public的函数,包括父类继承而来的 * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限 */ 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(ms[i].getName()+"("); //获取参数类型--->得到的是参数列表的类型的类类型 Class[] paramTypes = ms[i].getParameterTypes(); for (Class class1 : paramTypes) { System.out.print(class1.getName()+","); } System.out.println(")"); } } /** * 获取成员变量的信息 * @param obj */ public static void printFieldMessage(Object obj) { Class c = obj.getClass(); /** * 成员变量也是对象 * java.lang.reflect.Field * Field类封装了关于成员变量的操作 * getFields()方法获取的是所有的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); } } /** * 打印对象的构造函数的信息 * @param obj */ public static void printConMessage(Object obj){ Class c = obj.getClass(); /** * 构造函数也是对象 * java.lang. Constructor中封装了构造函数的信息 * getConstructors获取所有的public的构造函数 * getDeclaredConstructors得到所有的构造函数 */ //Constructor[] cs = c.getConstructors(); 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(")"); } } }
4)通过Class,Method来认识泛型的本质
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); // 结果true ——反射的操作都是编译之后的操作 // c1==c2结果返回true说明编译之后集合的泛型是去泛型化的
查看全部 -
int.class//int的类类型 String.class//String的类类型 .getName()//类的名称 .getSimpleName()//不带包名的类名 void关键字都存在类类型 class类的基本API Class c = obj.getClass();//传递的是哪个子类的对象 c就是该子类的类类型
查看全部 -
11111查看全部
-
反射可以绕过编译
查看全部 -
获取类对象的三种方法:
Foo f = new Foo(); Class c1 = f.getClass();
Class c2 = Foo.class;
Class c3 = Class.forName("package.Foo");
使用类类型获取该类的对象
Foo f = (Foo)c1.newInstance();
查看全部 -
Ok查看全部
-
在编译时刻加载类是静态类加载,在运行时刻加载类是动态类加载。范型是防止错误输入,在编译之后是去范型的。查看全部
-
new对象就是静态加载类,在编译时刻即加载所有可能用到的对象。查看全部
举报