不同阶段都可以获取类对象对象.getclass() (内存阶段)
test.class (元空间)
class.forname(“类全名:包名+类名”) :(硬盘)都没有进入内存空间就可以拿到对象
举例来说,当我们使用jdbc操作数据库时,在这个类进入内存之前,我们可以使用该类的完整名称——包名+类名,调用该类并使用
获取class类对象的方式的场景class.forname(“类全名”) :多用于配置文件,将类名定义在配置文件中,读取配置文件,加载类
类名.class : 多用于参数的传递
对象名.getclass():多用于对象获取类对象
总结:同一个类加载器加载的文件在一次程序运行过程中,只会被加载一次,无论使用哪种方式获得的类对象都是同一个
代码示例:
package com.reflect;public class testreflectperson { public static void main(string[] args) throws classnotfoundexception { //1.class.forname() class class1=class.forname("com.reflect.person"); system.out.println(class1); //2.类名.class class class2=person.class; system.out.println(class2); //2.对象名.getclass() class class3=new person().getclass(); system.out.println(class3); system.out.println(class1==class2); //true system.out.println(class2==class3); //true }}
class类对象的功能获取成员变量 : 取所有:类对象.getdeclaredfields() ,获取一个:类对象.getdeclaredfield()
设置值 set(object obj,object value)
获取值 get(object obj)
获取任意权限修饰的成员变量获取设置值,需要使用setaccessible(true)-----暴力反射
成员方法: 类对象.getdeclaredmethods()
执行方法 invoke(object object ,object… agrs) (参数个数任意,可有可无)
获取方法名getname()
构造方法: 类对象.getdeclaredconstructors()
虽然必须具备无参构造方法,但是使用 newinstance() 方法可以省略获取构造方法并获取对象的步骤
该方法需要实际情况构造方法赋实参
//获得构造方法对象, constructor cons1 = pcla.getdeclaredconstructor(string.class, int.class); person p2 = (person)cons1.newinstance("李四",19); system.out.println("p2:"+p2.getname());
newinstance()如果是创建无参构造方法去创建对象,可以使用类对象来创建对象,跳过获得构造方法对象
获取
获得类的名称:getname() 打印出全名:类名+包名
只想打印单独类名:getsimplename()
获取类的成员变量名称
属性文件:内容以等号连接形如k=v,
代码示例:
package com.reflect;import java.lang.reflect.constructor;import java.lang.reflect.field;import java.lang.reflect.method;public class testreflectperson { public static void main(string[] args) throws exception { /* //1.class.forname() class class1=class.forname("com.reflect.person"); system.out.println(class1); //2.类名.class class class2=person.class; system.out.println(class2); //2.类名.getclass() class class3=new person().getclass(); system.out.println(class3); system.out.println(class1==class2); system.out.println(class2==class3);*/ //获取对象 class tclass=class.forname("com.reflect.person"); //通过类对象获取成员变量们 field[] fields = tclass.getdeclaredfields(); system.out.println("获取person对象的所有属性对象"); for (field field:fields){ system.out.println(field); } //指定获取person对象的属性对象 system.out.println("指定获取person对象的属性对象"); field age=tclass.getdeclaredfield("age"); system.out.println("age:"+age); //通过类对象获取所有的构造方法 constructor[] constructors = tclass.getdeclaredconstructors(); system.out.println("获取person的所有构造方法对象"); for (constructor constructor:constructors){ system.out.println(constructor); } //通过类对象获取无参的构造方法 constructor constructor = tclass.getdeclaredconstructor(); system.out.println("constructor:"+constructor); //通过类对象获取有参的构造方法 constructor constructor1 = tclass.getdeclaredconstructor(string.class,int.class); system.out.println("constructor1:"+constructor1); //通过类对象获取所有的成员方法 method[] methods = tclass.getdeclaredmethods(); for (method method:methods){ system.out.println("method:"+method); } //通过类对象获取getage成员方法 method getage = tclass.getdeclaredmethod("getage"); system.out.println("getage:"+getage); //通过类对象获取getage成员方法 method setage = tclass.getdeclaredmethod("setage", int.class); system.out.println("setage:"+setage); }}
获取成员变量代码示例:
package com.reflect;import java.lang.reflect.field;public class testfield { public static void main(string[] args) throws exception { class pcla=person.class; /*//获取公共访问权限的成员变量 field[] fields = pcla.getfields(); for (field field:fields){ system.out.println("getfild:"+field); } system.out.println(); //获取所有访问权限的成员变量 field[] fielddes = pcla.getdeclaredfields(); for (field field:fielddes){ system.out.println("field:"+field); }*/ field name = pcla.getdeclaredfield("name"); system.out.println(name); person person=new person(); //暴力反射:获取任意访问权限修饰符的安全检查 name.setaccessible(true); //获取公共成员变量的值 object value = name.get(person); system.out.println(value); //获取任意访问权限的成员变量的值 object value2 = name.get(person); system.out.println("value2:"+value2); //设置任意访问权限的成员变量的值 name.set(person,"张三"); object value3=name.get(person); system.out.println("name:"+value3); }}
如何获取私有变量的值//暴力反射:获取任意访问权限修饰符的安全检查name.setaccessible(true);
根据有无主方法判断进程和线程进程:含有自己的主方法,可以依托自己的主方法启动,叫做进程
线程:没有自己的主方法,需要依赖其他工具来运行
例如:servlet就需要借助tomcate来运行,tomcate有自己的一个主方法
反射出现的背景(记住)举例:在servlet通过借助工具tomcate来运行时,tomacate运行项目时访问不到类的资源,由此产生了反射
tomcate为什么拿不到new的对象
详解:tomcate不可能通过new的方式来调用,因为tomacate是先产生写好的,类是后来写的,所以tomcate不知道new的对象的是什么,可以通过包扫描的方式来获取文件路径,但是这样也无法使用new的方式,由此产生了反射。
ate有自己的一个主方法
反射出现的背景举例:在servlet通过借助工具tomcate来运行时,tomacate运行项目时访问不到类的资源,由此产生了反射
tomcate为什么拿不到new的对象?
详解:tomcate不可能通过new的方式来调用,因为tomacate是先产生写好的,类是后来写的,所以tomcate不知道new的对象的是什么,可以通过包扫描的方式来获取文件路径,但是这样也无法使用new的方式,由此产生了反射。
tomcate想调用doget,dopost的方法时,因为这两个方法不是静态的,必须通过new对象才能调用,但是tomcate又不能创建对象,所以由此产生反射来获取文件
以上就是java反射机制的知识点有哪些的详细内容。
