什么是反射?反射机制是在运行状态中,它为java提供一种“操作对象”的能力,在运行状态下,通过class文件对象,可以调用到任何类里面的属性、方法、以及构造方法,包括私有的,所有的类在反射机制面前都是透明的
自己的概括:通过class文件对象可以看到这个类里面的所有东西,并且可以使用和修改
反射的前提是获取class文件对象((字节码对象),那么一共有三种方式获取:
class.forname(“全类名”) ----通过class类的静态方法(最常用)
类名.class
对象.getclass()
//方式1:获取字节码对象,class.forname("全类名")class cla1 = class.forname("study01.person");//方式2: 类名.classclass cla2 = person.class;//方式3:对象.getclass();person per = new person();class cla3 = per.getclass();//这三个class对象都是由person这个类生成的//那么我们看一下这三个字节码对象是不是同一个:system.out.println(cla1==cla2);system.out.println(cla2==cla3);
//输出结果: 两个true
结论:
字节码对象在类加载的时候就产生,并且只有一个
无论哪种方式获取字节码对象都是同一个字节码对象
通过反射来获取类中的属性:
获取到class字节码对象后,我们就可以通过字节码对象来获取到我们想要获取的类的属性、方法、构 造方法、以及private修饰的。
部分class方法:
demo演示:1、建一个person类,里面有两个public和两个private的属性(不设置构造和get/set,就是看反射能不能得到里面的值)
public class person { private string name; //名字 private int age = 18; //年龄 public int id = 123; //身份证 public string sex; //性别 @override public string tostring(){ return "姓名"+name+"年龄:"+age+"id:"+id+"性别:"+sex; }}
测试类:
public class test { public static void main(string[] args) throws classnotfoundexception { //获取class文件对象,用最常用的通过class类的静态方法 class per = class.forname("test01.person"); //这里是传入全路径!!从最外层的包名开始! //使用getfields()方法获取全部被public修饰的属性(方法上面的截图有) //并且返回的是field类型的数组 field fields[] = per.getfields(); for (field field:fields) { system.out.println(field); } }}
输出:
我们成功的获取到了person类中全部public属性
2、也可以获取全部的属性,包括私有的:(其他代码就不重写啦)
for (field field : per.getdeclaredfields()) { system.out.println(field); }
输出:
3、获取公有的属性,并且修改这个值:
field f = per.getfield("sex"); system.out.println(f); //获取一个对象: object obj = per.getconstructor().newinstance(); //修改值: f.set(obj,"男"); person p = (person)obj; system.out.println(p.sex);
输出:
4、获取私有的属性,并且修改这个值: 这里把上面修改公有属性的值也连起来:
person p = (person)obj; //获取公有字段并调用,并修改 field f = per.getfield("sex"); //获取一个对象: object obj = per.getconstructor().newinstance(); f.set(obj,"男"); //将sex的属性修改成了 男 //调用私有的属性,并修改 f = per.getdeclaredfield("name"); //在访问私有的属性的值之前,先要设置运行访问↓ //在访问之前忽略访问权限的检查,叫暴力反射 f.setaccessible(true); f.set(obj,"张三"); system.out.println("person里面的信息是:"+p.tostring()); }}
输出:
通过反射来获取类中的方法(公有、私有、构造):
person类:
public class person { private string name; //名字 private int age = 18; //年龄 public int id = 123; //身份证 public string sex ; //性别 //构造: public person() {} public person(string name, int age, int id, string sex) { this.name = name; this.age = age; this.id = id; sex = sex; } //无参公有方法: public void eat(){ system.out.println("我会吃饭"); } //有参公有方法: public void eat(string food){ system.out.println("我在吃:"+food); } //有参私有方法 private void play(string name){ system.out.println(name+"在玩"); }}
测试类:
public class test { public static void main(string[] args) throws nosuchmethodexception, invocationtargetexception, illegalaccessexception { //获取到person以及父类object里面的public方法: system.out.println("-----获取到person以及父类object里面的public方法↓-----"); for (method method : person.class.getmethods()) { system.out.println(method); system.out.println("方法名:"+ method.getname()); } //获取到person里面的方法,包括私有 system.out.println("-----获取到person里面的方法,包括私有↓-----"); for (method method:person.class.getdeclaredmethods()) { system.out.println(method.getname()+" "); } //按照方法名获取到person中的eat方法: system.out.println("-----根据方法名获取到person类中的eat方法↓-----"); method earmethod1 = person.class.getmethod("eat"); person per = new person(); //通过invoke(object,param...)来调用指定的方法 earmethod1.invoke(per); //使用反射调用有参方法; system.out.println("-----使用反射调用有参方法(传入参数)↓-----"); method earmethod2 = person.class.getmethod("eat",string.class); earmethod2.invoke(per,"牛肉"); //通过暴力反射获取到私有的play方法: system.out.println("-----通过暴力反射获取到私有的play方法传入参数)↓-----"); method earmethod3 = person.class.getdeclaredmethod("play", string.class); //在访问私有的属性的方法之前,先要设置运行访问 earmethod3.setaccessible(true); earmethod3.invoke(per,"小王"); }
输出:
-----获取到person以及父类object里面的public方法↓-----
public void test02.person.eat(java.lang.string)
方法名:eat
public void test02.person.eat()
方法名:eat
public final void java.lang.object.wait() throws java.lang.interruptedexception
方法名:wait
public final void java.lang.object.wait(long,int) throws java.lang.interruptedexception
方法名:wait
public final native void java.lang.object.wait(long) throws java.lang.interruptedexception
方法名:wait
public boolean java.lang.object.equals(java.lang.object)
方法名:equals
public java.lang.string java.lang.object.tostring()
方法名:tostring
public native int java.lang.object.hashcode()
方法名:hashcode
public final native java.lang.class java.lang.object.getclass()
方法名:getclass
public final native void java.lang.object.notify()
方法名:notify
public final native void java.lang.object.notifyall()
方法名:notifyall
以上就是java反射机制原理实例分析的详细内容。