反射
来源:互联网 发布:导出数据库命令 编辑:程序博客网 时间:2024/06/11 04:18
反射
反射的操作是编译之后的操作---运行时刻的操作,所有下边方法的反射,变量的反射都是绕过编译,在运行时刻来执行的。
Class类的使用
- 一个类也属于对象,它是java.lang.Class类的对象
public class Foo { public void print(int a,String b){ System.out.println("...."); } public static void main(String []args){ Foo foo1=new Foo(); }}
Class类的实例变量的表示<以上面的代码为例>
* Class c1=Foo.class;//这个代码也告诉我们,任何一个类都有一个隐含的静态成员变量class。
* Class c2=foo1.getClass();//已知该类的对象,通过getClass()方法来获取
* Class c3=null;
c3=Class.forName(“包名+类名”);
c1、c2、c3是Foo类的类类型,且c1=c2,c2=c3因为一个类只可能是Class类的一个实例变量。
我们可以通过(类类型)c1、c2、c3来创建Foo类的实例
Foo foo2=c1.newInstance();//前提是要有无参数的构造方法,因为通过这种方式创建类的对象时,它会默认去调用无参数的构造方法。
方法的反射
Method类,方法对象,一个方法就是一个Method对象。
方法的反射使用
* 获取方法:
Class c1=foo1.getClass();
Method[] ms=c1.getMethods();
getMethods()方法可以获取到所有的public方法,包括由父类继承而来的方法。
getDeclaredMethods()方法可以获取到该类自己声明的所有方法,不包含由父类继承而来的方法,不问访问权限。
getMethod()方法可以获取到public方法,包括由父类继承而来的方法。里边有两个参数(方法名,参数列表)
Method m=c1.getMethod("print",Class[]{int.class,String.class});
getDeclaredMethod()方法可以获取到该类自己声明的方法,不包含由父类继承而来的方法,不问访问权限。里边有两个参数(方法名,参数列表)
* 方法的反射操作
在使用反射之前,我们调用一个方法,通常都是这样来实现的:
foo1.print(6,"a");
在反射中,我们应该这么来做:
Method m=c1.getMethod("print",new Class[]{int.class,String.class});
Object o=m.invoke(foo1,new Object[]{6,"a"});//方法如果没有返回值,则返回空,如果有返回值,则返回具体的返回值。
成员变量的反射
成员变量的反射使用
Class c1=foo1.getClass();Field[] fd=c1.getFields();
getFields()方法可以获取到所有的public变量
getDeclaredConstructors()方法可以获取到该类自己声明的所有构造方法
构造函数的反射
构造函数的反射使用
Class c1=foo1.getClass();Constructor[] cs=c1.getConstructors();
getConstructors()方法可以获取到所有的public构造方法
getDeclaredFields()方法可以获取到该类声明的所有变量
通过Class,Method了解泛型的本质
一般情况下,我们进行集合的元素添加时都会经历编译时期。而编译之后,集合的泛型是去泛型化的。
去泛型化:
ArrayList list=new ArrayList();ArrayList<String> list1 = new ArrayList<>();Class c1=list.getClass();Class c2=list1.getClass();System.out.println(c1=c2);//结果为true
ArrayList list=new ArrayList();ArrayList<String> list1 = new ArrayList<>();list1.add(20);//这里会有错误,类型错误
而如果我们通过方法的反射来绕过编译时期:
ArrayList list=new ArrayList();ArrayList<String> list1 = new ArrayList<>();Class c1=list1.getClass()Method m=null;try { m = c1.getMethod("add", Object.class); m.invoke("add",20);//这样就绕过了编译}catch (Exception e){ e.printStackTrace();}
就可以将”20”添加到list1中了。
动态加载类
- 静态加载:编译时刻加载类
- 动态加载:运行时刻加载类–Class.forName()方法就包含了动态加载类
静态加载
通过new 来创建对象,是静态加载类,在编译时刻就需要加载所有可能用到的类。
动态加载
Class c4=double.class;//double数据类型的类类型
Class c5=Double.class;//Double类的类类型
类类型
基本数据类型都包含类类型
Void关键字同样具有类类型
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 设计模式(十九) 备忘录模式
- Hex、bin、axf、elf格式文件小结
- shiro验证【springboot mybatis个人博客系统(二)】
- Spring AOP 演化过程(二):基于代理的经典Spring AOP
- 1. Java NIO系列之介绍
- 反射
- tensorflow 语法
- Spring mvc+Spring+hibernate整合
- hihocoder #1152 : Lucky Substrings
- C++ STL中Map的按Key排序和按Value排序
- Ubuntu16.04 安装搜狗输入法
- 使用JAVA理解程序逻辑第二章
- React-Native-Navigator导航条-反向传值
- 成员变量和局部变量的区别?