您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

Java基础入门之反射

2024/6/6 16:34:22发布42次查看
今天学到java基础中的反反射。依照我学习后的个人理解呢,反射就是一套获取类、属性、方法等的工具吧。(其实,感觉学完反射后,有点像喝凉水,解渴但确实我也没体会出它有什么味道,我可能没有学到精髓吧。自己都能感觉少点什么。这是我java基础学习的最后一个部分了,我想再复习一遍,然后再学习其他的。也想有时间看看jvm和计算机系统之类的书。总觉得自己不是科班出身,思路上有些短板。要继续努力咯。)
在学习反射之前,我先回忆了一下可变参数。
public static void main(string[] args) {             test();//调用方法1test(java);//调用方法2test(java,工程师);//调用方法3test(new string[]{水果,电器});//调用方法4        }    static void test(string ... array){  //直接打印:system.out.println(array);for(string str:array){  //利用增强for遍历            system.out.println(str);             }         }
之所以回忆可变参数呢,是因为它与反射的应用有点像。如果将一个方法定义为可变参数,在调用的时候传参的限制就少了一大截。在反射当中呢,我们利用一些方法,得到类的实例对象,那么类里面的方法、属性等,就尽收眼底。在前面的学习中知道了,方法、属性等都有静态的和非静态的,私有的和非私有的之分,那么我们在调用的时候,想取哪一块,或者说只想取得哪一块,是不是也可以想个办法实现呢?这时候,反射就出现了,现今我对它的理解就只有这些了。继续努力吧。
一、反射的概念
java反射机制是在运行状态中(注意不是编译的时候),对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
java反射机制主要提供了以下功能:
-- 在运行时判断任意一个对象所属的类;
-- 在运行时构造任意一个类的对象;
-- 在运行时判断任意一个类所具有的成员变量和方法;
-- 在运行时调用任意一个对象的方法;
-- 生成动态代理。
jdk中,与反射相关的类,主要有以下几个
//java.lang包下
class 类
class 类的实例表示正在运行的 java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 class 对象。基本的 java 类型(boolean、byte、char、short、int、long、float 和 double)    和关键字 void 也表示为 class 对象。
关于class类jdk里面的解释:
public finalclass class<t> implements java.io.serializable,                               java.lang.reflect.genericdeclaration,                               java.lang.reflect.type,                               java.lang.reflect.annotatedelement {private static final int annotation= 0x00002000;private static final int enum      = 0x00004000;private static final int synthetic = 0x00001000;private static native void registernatives();static {         registernatives();     }/* * constructor. only the java virtual machine creates class      * objects.     */private class() {}
class类jdk里的一些方法(个人觉得读起来很舒服,自己想记录一下)
public string tostring() {return (isinterface() ? interface  : (isprimitive() ?  : class ))+ getname();     }//应该是三元表达式
public static class<?> forname(string classname)throws classnotfoundexception {         class<?> caller = reflection.getcallerclass();return forname0(classname, true, classloader.getclassloader(caller), caller);     }
public static class<?> forname(string name, boolean initialize,                                    classloader loader)throws classnotfoundexception     {         class<?> caller = null;         securitymanager sm = system.getsecuritymanager();if (sm != null) {// reflective call to get caller class is only needed if a security manager// is present.  avoid the overhead of making this call otherwise.caller = reflection.getcallerclass();if (loader == null) {                 classloader ccl = classloader.getclassloader(caller);if (ccl != null) {                     sm.checkpermission(                         securityconstants.get_classloader_permission);                 }             }         }return forname0(name, initialize, loader, caller);     }
private static native class<?> forname0(string name, boolean initialize,                                             classloader loader,                                             class<?> caller)throws classnotfoundexception;
public t newinstance()throws instantiationexception, illegalaccessexception     {if (system.getsecuritymanager() != null) {             checkmemberaccess(member.public, reflection.getcallerclass(), false);         }// note: the following code may not be strictly correct under// the current java memory model.// constructor lookupif (cachedconstructor == null) {if (this == class.class) {throw new illegalaccessexception(can not call newinstance() on the class for java.lang.class);             }try {                 class<?>[] empty = {};final constructor<t> c = getconstructor0(empty, member.declared);// disable accessibility checks on the constructor// since we have to do the security check here anyway// (the stack depth is wrong for the constructor's// security check to work)                java.security.accesscontroller.doprivileged(new java.security.privilegedaction<void>() {public void run() {                                 c.setaccessible(true);return null;                             }                         });                 cachedconstructor = c;             } catch (nosuchmethodexception e) {throw new instantiationexception(getname());             }         }         constructor<t> tmpconstructor = cachedconstructor;// security check (same as in java.lang.reflect.constructor)int modifiers = tmpconstructor.getmodifiers();if (!reflection.quickcheckmemberaccess(this, modifiers)) {             class<?> caller = reflection.getcallerclass();if (newinstancecallercache != caller) {                 reflection.ensurememberaccess(caller, this, null, modifiers);                 newinstancecallercache = caller;             }         }// run constructortry {return tmpconstructor.newinstance((object[])null);         } catch (invocationtargetexception e) {             unsafe.getunsafe().throwexception(e.gettargetexception());// not reachedreturn null;         }     }
public string getname() {         string name = this.name;if (name == null)this.name = name = getname0();return name;     }
// cache the name to reduce the number of calls into the vmprivate transient string name;private native string getname0();
还有很多,暂不记录了。。。。。
//java.lang.reflect  包下 constructor 代表构造函数 method 代表方法 field 代表字段 array 与数组相关
二、class类的说明
常用的得到class类的方法 // class c=new class(); 不可以,因为它被私有化了1) class c=student.class;   //用类名.class 就可以得到class类的实例2) student stu=new student(); class c=stu.getclass();   //用对象名.getclass();3) class c=class.forname(com.mysql.jdbc.driver);
//例一  通过调用无参的构造函数,创建类对象public class test {public static void main(string[] args) throws instantiationexception, illegalaccessexception {     class clazz=dog.class;     dog dog=(dog)clazz.newinstance();     dog.shout();     } }             class dog{void shout(){     system.out.println(汪汪);     } }
通过例一,我并没有看出来利用反射的好处,呃~~
//例二 上例的改写class clazz=class.forname(com.weiboo.dog); //注意,必须是类的全部dog dog=(dog)clazz.newinstance(); dog.shout();
//例三  (运行本类,dog 和 cat 类,必须有一个无参的构造函数)public class test {public static void main(string[] args) throws instantiationexception, illegalaccessexception, classnotfoundexception {     dog dog=(dog)createobj(dog.class);     dog.shout();                      cat cat=(cat)createobj(cat.class);     cat.speak();     }                     static object createobj(class clazz) throws instantiationexception, illegalaccessexception{return clazz.newinstance();  //调用的是newinstance() 方法创建的类对象,它调用的是类中无参的构造方法}     }         class dog{void shout(){     system.out.println(汪汪);     } }         class  cat{void speak(){     system.out.println(喵~~~);             } }
三、反射中的其他的类的说明
1) constructor
代表类中的构造函数     class 类提供了以下四个方法
public constructor<?>[] getconstructors()      //返回类中所有的public构造器集合,默认构造器的下标为0
public constructor<t> getconstructor(class<?>... parametertypes)   //返回指定public构造器,参数为构造器参数类型集合
public constructor<?>[] getdeclaredconstructors()  //返回类中所有的构造器,包括私有的
public constructor<t> getdeclaredconstructor(class<?>... parametertypes) //返回任意指定的构造器,包括私有的
import java.lang.reflect.constructor;import java.lang.reflect.invocationtargetexception;//例子 得到某个类中指定的某个构造函数所对应的 constructor对象class test2 {public static void main(string[] args) throws instantiationexception,             illegalaccessexception, classnotfoundexception,             nosuchmethodexception, securityexception, illegalargumentexception,             invocationtargetexception {         class<cat> clazz = cat.class;         constructor<cat> c = clazz.getconstructor(int.class, string.class);         cat cat = (cat) c.newinstance(20, 加飞猫);         cat.speak();     }class cat {private string name;private int age;public cat(int age, string name) {this.age = age;this.name = name;         }public cat(string content) {             system.out.println(这是构造函数得到的参数 + content);         }void speak() {             system.out.println(喵~~~);             system.out.println(我的名字是 + this.name + 我的年龄是 + this.age);         }     } }
/例子 访问类中的私有构造函数 class clazz=cat.class; constructor c=clazz.getdeclaredconstructor(); c.setaccessible(true);  //让私有成员可以对外访问cat cat=(cat) c.newinstance();  //对于私有的来说,能不能行?cat.speak();
2) method 代表类中的方法
class 类提供了以下四个方法
public method[] getmethods()    //获取所有的共有方法的集合,包扩继承的
public method getmethod(string name,class<?>... parametertypes) // 获取指定公有方法 参数1:方法名 参数2:参数类型集合 
public method[] getdeclaredmethods()  //获取所有的方法(包扩私有的),除了继承来的
public method getdeclaredmethod(string name,class<?>... parametertypes) //获取任意指定方法,除来了继承来的
//调用类中的私有方法main 函数 class  clazz=cat.class;//调用一个不带参数的方法method m=clazz.getdeclaredmethod(speak); m.setaccessible(true); cat c=new cat(); m.invoke(c);  //让方法执行                                      //调用一个带参数的方法method m=clazz.getdeclaredmethod(eat, int.class,string.class); m.setaccessible(true); cat c=new cat(); m.invoke(c, 20,鱼);     class  cat{private string name;private int age;                          cat(){     }public cat(int age,string name){this.age=age;this. name=name;     }                         public cat(string content){     system.out.println(这是构造函数得到的参数+content);     }                        private void speak(){     system.out.println(喵~~~);             system.out.println(我的名字是+this.name+我的年龄是+this.age);     }                        private void eat(int time,string something){     system.out.println(我在+time +分钟内吃了一个+something);     } }
例子 查看一个类中的所有的方法名public static void main(string[] args) throws instantiationexception, illegalaccessexception, classnotfoundexception, nosuchmethodexception, securityexception, illegalargumentexception, invocationtargetexception {     class  clazz=cat.class;                        /*method []  methodlist=clazz.getmethods() ; //查看所有的公有方法,包扩继承的     for(method m:methodlist){     system.out.println(m.getname());     }*/method []  methodlist=clazz.getdeclaredmethods(); //查看所有的方法,包扩私有的,但不包扩继承的for(method m:methodlist){     system.out.println(m.getname());     } }
3) field 代表字段
public field getdeclaredfield(string name)  // 获取任意指定名字的成员
public field[] getdeclaredfields()  // 获取所有的成员变量,除了继承来的
public field getfield(string name)  // 获取任意public成员变量,包含继承来的
public field[] getfields() // 获取所有的public成员变量
//例子 访问字段public class test {public static void main(string[] args) throws exception {     class clazz=cat.class;                         /* field field= clazz.getfield(home);     cat c=new cat();     object obj=field.get(c);     system.out.println(obj); // 家*/      cat cat=new cat();     field  [] fieldlist= clazz.getdeclaredfields();for(field f:fieldlist){  //访问所有字段f.setaccessible(true);     system.out.println(f.get(cat));                                     }         } }                             class  cat{private string name=黑猫;private int age=2;public string home=家; }
四、反射的应用
用一个例子来说明一下,比较两个同类对象中的所有字段,不同的并把它输出来。
import java.lang.reflect.field;import java.util.hashmap;import java.util.map;public class test {public static void main(string[] args) throws exception {         student stu1 = new student(24, 李磊, 工程大学, 女);         student stu2 = new student(20, 王一, 师大, 男);         map<string, string> map = compare(stu1, stu2);for (map.entry<string, string> item : map.entryset()) {             system.out.println(item.getkey() + : + item.getvalue());         }     }static map<string, string> compare(student stu1, student stu2) {         map<string, string> resultmap = new hashmap<string, string>();         field[] fieldlis = stu1.getclass().getdeclaredfields(); // 得到stu1所有的字段对象try {for (field f : fieldlis) {                 f.setaccessible(true); // 别忘了,让私有成员可以对外访问object v1 = f.get(stu1);                 object v2 = f.get(stu2);if (!(v1.equals(v2))) {                     resultmap.put(f.getname(), stu1的值是 + v1 +    stu2的值是                             + v2);                 }             }         } catch (exception ex) {             ex.printstacktrace();         }return resultmap;     } }class student {private string name;private string school;private string sex;public student(int age, string name, string school, string sex) {this.age = age;this.name = name;this.school = school;this.sex = sex;     }private int age;public int getage() {return age;     }public void setage(int age) {this.age = age;     }public string getname() {return name;     }public void setname(string name) {this.name = name;     }public string getschool() {return school;     }public void setschool(string school) {this.school = school;     }public string getsex() {return sex;     }public void setsex(string sex) {this.sex = sex;     } }
以上就是java基础入门之反射的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product