反射
来源:互联网 发布:artrage mac破解 编辑:程序博客网 时间:2024/05/18 03:30
我所理解的反射:
根据一个已经实例化了的对象来还原类的完整信息
反射的定义:
JAVA反射机制是在运行状态中,对任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取以及动态调用对象的方法的功能成为java语言的反射机制。
(在java中,Object类是所有类的父类,同样,所有类的实例化对象也都是Class类的实例)
1.获取类(类的实例化)
(1)对象.getclass()
(2)类.class
(3)Class.forName()
(1)(2)(3)得到的是类类型,通过类类型可以获取该类的各种信息
2.创建对象
Class类中有一个方法叫做newInstance( ),它可以用来创建一个Class类对象的新实例
3.代码实例
实例化
package com.imooc.reflect;public class CalssDemo1 { public static void main(String[] args){ // TODO Auto-generated method stub Foo foo1=new Foo(); //Foo这个类也是一个实例对象,Class类的实例对象 //任何一个类都是class的实例对象,有三种表示方式 //1.任何一个类都有一个隐含的成员变量class Class c1=Foo.class; //2.已知该类的对象,通过getClass()方法 Class c2=foo1.getClass(); //c1 c2表示了Foo类的类类型(class type) //3. Class c3=null; try { c3=Class.forName("com.imooc.reflect.Foo"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } //c1 c2 c3肯定是相等的,因为她们都代表了Foo类的类类型 System.out.println(c1==c2); System.out.println(c2==c3); //通过类的类类型创建该类的对象实例,需要有无参数的构造方法 //通过类类型可以获得该类的很多信息,什么方法属性之类的!! try { Foo foo=(Foo)c1.newInstance(); foo.print(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }class Foo{ void print() { System.out.println("first!"); }}
获取类的信息 包括类的成员函数 成员变量
package com.imooc.Demo2;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ClassUtil { /* 打印类的信息,包括类的成员函数,成员变量 */ public static void printFieldMessage(Object obj) { //获取类的信息,首先获取类的类型,有三种方式,使用第二种 Class c=obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型 System.out.println("类的名称是:"+c.getName()); /* 1.Method类,方法对象 2.一个成员方法就是一个Method对象 3.getMethods()方法获取的是所以的public的函数,包括父类继承而来的 3.getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限 */ Method[] ms=c.getMethods(); for(int i=0;i<ms.length;i++) { //得到方法的返回值类型的类类型 Class returnType=ms[i].getReturnType(); System.out.print(returnType.getName()+" "); //得到方法的名称 System.out.println(ms[i].getName()+","); //获取参数类型-->得到的是参数列表的类型的类类型 Class[] paramTypes=ms[i].getParameterTypes(); for(Class class1:paramTypes) { System.out.println(class1.getName()+","); } /* 1.成员变量也是对象 2.java.lang.reflect.Field 3.Field类封装了关于成员变量的操作 4.getFields()方法获取的是所以public的成员变量的信息 5.getDeclaredFields获取的是该类自己声明的成员变量的信息 */ 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); } } } }
方法反射的基本操作
package com.imooc.Demo2;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class MethodDemo1 { public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { // TODO Auto-generated method stub // 获取print(int,int)方法,即获取类的信息,获取类的类类型 A a1 = new A(); Class c = a1.getClass(); /* * 2.获取方法 名称和参数列表来决定 getMethod获取的是 public的方法 getDeclaredMethod自己声明的方法 */ try { //int.class与string.class是方法对象 Method m = c.getMethod("print", int.class, int.class); // 方法的反射操作 // a1.print(10, 20);方法的反射操作是用m对象来进行方法 调用,和a1.print相同 //方法如果没有返回值返回null,如果有返回值返回具体的返回值 Object o = m.invoke(a1, 10,20); System.out.println("------------------"); //获取方法print(string,string) Method m1=c.getMethod("print", String.class,String.class); o=m1.invoke(a1, "hello","world"); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block 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()); }}
通过反射了解集合泛型的本质
package com.imooc.Demo2;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;public class MethodDemo4 { public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { // TODO Auto-generated method stub ArrayList list=new ArrayList(); ArrayList<String> list1=new ArrayList<String>(); list1.add("hello"); //list1.add(2)错误 Class c1=list.getClass(); Class c2=list1.getClass(); System.out.println(c1==c2); //反射的操作都是编译之后的操作 /* * 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);//foreach遍历就抛出异常 } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
阅读全文
0 0
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 使用 react 总结
- 1163 最高的奖励-51Nod
- Java:volatile的作用
- Offer——排序算法
- pair
- 反射
- css-响应式布局
- Linux应用程序开发工具-GDB调试与Make
- python:matplotlib及pandas绘图(2)
- Error:JAVA_HOME is not set and could not be found 解决般的法
- <c语言经典100例>c24 递归求n!
- java列表框应用
- Java基础之随机生成数字和字母
- 2017.10.2 loli测试