反射是结构规划的灵魂,只有学好了反射,才干规划出好的结构
一.反射的概述
Java反射机制是在运转状况中,关于恣意一个类,都能够知道这个类的一切特点和办法;关于恣意一个目标,都能够调用它的恣意办法和特点;这种动态获取信息以及动态调用目标办法的功能便是Java言语的反射机制.简略来说,便是反射能够协助咱们在动态运转的时分,关于恣意一个类,能够取得其一切办法,一切的变量(是一切的!包含私有!)
反射的效果
获取某些类的一些变量,调用某些类的私有办法.(举个栗子,例如在Android开发中咱们能够用来敞开WiFi热点,调用WifiManager中的setWifiApEnabled()办法)
添加代码的灵活性.(许多干流结构都运用了反射技能,像ssm结构都采用两种技能xml做配置文件+反射技能)
而咱们要想运用反射,就要对反射的常用目标有个根本了解
Class
Class类的实例表明正在运转的Java应用程序中的类和接口
Constructor
关于类的单个结构办法的信息以及对它的拜访权限
Field
Field供给有关类或接口的单个字段的信息,以及对它的动态拜访权限.
Method
Method供给关于类或接口上单独某个办法的信息
反射在内存中的姿态大约长这样
在这儿刺进图片描绘
这是一个简略的Animal类,这个Animal.java文件,想要被履行的话,首先会被编译成Animal.class文件.而Animal.class想要被履行的话,就会被类加载器加载到JVM中履行,JVM就会将它加载到内存,而加载之后,咱们的字节码文件Animal.class在内存中也会有一个目标的表明,别忘了Java言语有句话咋说的,”万事万物,皆为目标”.而.class文件在内存中的目标便是Class目标,所以说取得了Class,才干取得它的结构办法,特点以及办法,相对应的结构办法在内存中对应的是Constructor目标,特点对应的便是Field,而办法呢对应的便是Method,可是不论咱们想要取得结构办法,特点仍是办法,前提都是咱们先取得Class目标.
二.Class类
Java中java.lang.Class类用于表明一个类的字节码(.class)文件
如何得到某个class文件对应的Class目标
已知类和目标的情况下
类名.class
目标.getClass()—Object类供给
未知类和目标的情况下
Class.forName(“包名.类名”)
Class类代表某个类的字节码,并供给了加载字节码的办法:forName(“包名.类名”),forName办法用于加载类字节码到内存中,并封装成一个Class目标.
packageJavaReflectTest;publicclassAnimal{publicStringname;privateintid;publicAnimal(){System.out.println(“我是无参结构办法”);}publicAnimal(intid,Stringname){this.setId(id);this.setName(name);System.out.println(“我是有参结构办法”);}publicvoideat(){System.out.println(“我是公有办法”);}privatevoiddrink(){System.out.println(“我是私有办法”);}privatevoidplay(Stringname,Stringsex){System.out.println(“我是私有带参办法”);}@OverridepublicStringtoString(){return”Animal{“+”name='”+name+’\”+”,id=”+id+’}’;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetId(){returnid;}publicvoidsetId(intid){this.id=id;}}
packageJavaReflectTest;publicclassClassTest{/**
*取得Class目标
*1.经过类名.class
*2.目标.getClass()
*3.Class.forName();
*/publicvoiddemo1()throwsClassNotFoundException{//1.经过类名.class的办法Classclass1=Animal.class;//2.经过目标.getClass()的办法Animalanimal=newAnimal();Classclass2=animal.getClass();//3.Class类forName();取得(推荐)Classclass3=Class.forName(“JavaReflectTest.Animal”);}publicstaticvoidmain(String[]args){}}
这三种取得Class目标的办法,推荐运用第三种办法,因为咱们通常做反射的时分,都是在不知道类的实例的时分进行操作的,注意第三种办法经过Class.forName();来取得Class目标的时分,会抛出一个ClassNotFoundException没有发现类的反常,假如咱们Class.forName(“途径”);途径写错了或许没有找到这个类的时分,就会抛出这个反常,当然这个反常处理,你能够挑选try…catch处理也能够先向上抛,我这儿为了便利,就直接向上抛了
三.Constructor类
Constructor类的实例目标代表类的一个结构办法
得到某个类一切的结构办法
Constructor[]constructors=Class.forName(“java.lang.String”).getConstructors();
得到指定的结构办法并调用
Constructorconstructor=Class.forName(“java.lang.String”).getConstructors(String.class);
Stringstr=(String)constructor.newInstance(“abc”);
Class类的newInstance()办法用来调用类的默认结构办法
Stringobj=(String)Class.forName(“java.lang.String”).newInstance();
packageJavaReflectTest;importjava.lang.reflect.Constructor;publicclassConstructorTest{/**
*取得无参结构办法
*/publicvoiddemo1()throwsException{//取得类的字节码文件对应的目标:Classclass1=Class.forName(“JavaReflectTest.Animal”);Constructorc=class1.getConstructor();Animalanimal=(Animal)c.newInstance();//相当于Animalanimal=newAnimal();}/**
*取得有参结构办法
*/publicvoiddemo2()throwsException{Classclass1=Class.forName(“JavaReflectTest.Animal”);Constructorc=class1.getConstructor(int.class,String.class);Animalanimal=(Animal)c.newInstance(2,”山公”);//相当于Animalanimal=newAnimal(2,”山公”);System.out.println(animal.toString());}publicstaticvoidmain(String[]args)throwsException{ConstructorTestc=newConstructorTest();c.demo1();System.out.println(“————“);c.demo2();}}
运转成果
在这儿刺进图片描绘
四.Field类
Field类代表某个类中的一个成员变量,并供给动态的拜访权限
Field目标的取得
Field[]fields=c.getFields();//取得一切public特点(包含父类承继)
Field[]fields=c.getDeclaredFields();//取得一切声明的特点
得到指定的成员变量
Fieldname=c.getField(“name”);
Fieldname=c.getDeclaredField(“name”);
设置Filed变量是否能够拜访
field.setAccessible(boolean);
-Field变量值的读取,设置
field.get(obj);
filed.set(obj,value);
packageJavaReflectTest;importjava.lang.reflect.Field;publicclassFieldTest{//测验共有特点publicvoiddemo1()throwsException{//取得ClassClassclass1=Class.forName(“JavaReflectTest.Animal”);//取得特点:Fieldfield=class1.getField(“name”);//操作特点:Animalanimal=(Animal)class1.getConstructor().newInstance();field.set(animal,”老虎”);//animal.name=”老虎”;//获取值Objectobj=field.get(animal);System.out.println(obj);System.out.println(animal);//这样会主动调用toString()办法}//测验私有办法publicvoiddemo2()throwsException{//取得ClassClassclass1=Class.forName(“JavaReflectTest.Animal”);//取得私有特点:Fieldfield=class1.getDeclaredField(“id”);//操作特点:Animalanimal=(Animal)class1.getConstructor().newInstance();//私有特点,需求设置一个可拜访的权限field.setAccessible(true);field.set(animal,1);//获取值:Objectobj=field.get(animal);System.out.println(obj);System.out.println(animal);}publicstaticvoidmain(String[]args)throwsException{FieldTestfieldTest=newFieldTest();fieldTest.demo1();System.out.println(“—————-“);fieldTest.demo2();}}
效果图
在这儿刺进图片描绘
五.Method类
Method类代表某个类中的一个成员办法
Method目标的取得
取得一切办法
getDeclaredMethods()
getMethods()
-取得指定的办法
getDeclaredMethod(Stringname,Class…parameterTypes)
getMethod(Stringname,Class…parameterTypes)
经过反射履行办法
invoke(Objectobj,Object…args)
packageJavaReflectTest;importjava.lang.reflect.Method;publicclassMethodTest{//测验公有办法publicvoiddemo1()throwsException{//获取Class目标Classclass1=Class.forName(“JavaReflectTest.Animal”);//实例化Animalanimal=(Animal)class1.getConstructor().newInstance();//取得公有办法Methodmethod=class1.getMethod(“eat”);//履行该办法method.invoke(animal);//相当于animal.eat();}//测验私有办法publicvoiddemo2()throwsException{//获取Class目标Classclass1=Class.forName(“JavaReflectTest.Animal”);//实例化Animalanimal=(Animal)class1.getConstructor().newInstance();//取得私有办法Methodmethod=class1.getDeclaredMethod(“drink”);//设置私有的拜访权限method.setAccessible(true);//履行该办法method.invoke(animal);//相当于animal.drink();}publicvoiddemo3()throwsException{//获取Class目标Classclass1=Class.forName(“JavaReflectTest.Animal”);//实例化Animalanimal=(Animal)class1.getConstructor().newInstance();//取得私有带参的办法Methodmethod=class1.getDeclaredMethod(“play”,int.class,String.class);//设置私有的拜访权限method.setAccessible(true);//履行该办法Objectobj=method.invoke(animal,2,”孔雀”);//这是有返回值的情况假如没有返回值能够直接写method.invoke(animal,2,”孔雀”);System.out.println(obj);//打印返回的东西,没有便是null}//测验私有带参数的办法publicstaticvoidmain(String[]args)throwsException{MethodTestmethodTest=newMethodTest();methodTest.demo1();System.out.println(“——————–“);methodTest.demo2();System.out.println(“——————–“);methodTest.demo3();}}
广州天河区珠江新城富力盈力大厦北塔2706
020-38013166(网站咨询专线)
400-001-5281 (售后服务热线)
深圳市坂田十二橡树庄园F1-7栋
Site/ http://www.szciya.com
E-mail/ itciya@vip.163.com
品牌服务专线:400-001-5281
长沙市天心区芙蓉中路三段398号新时空大厦5楼
联系电话/ (+86 0731)88282200
品牌服务专线/ 400-966-8830
旗下运营网站:
Copyright © 2016 广州思洋文化传播有限公司,保留所有权利。 粤ICP备09033321号