how2j.cn

通过反射机制,调用一个对象的方法

步骤 1 : 调用方法   
步骤 2 : 练习-调用方法   
步骤 3 : 答案-调用方法   

步骤 1 :

调用方法

首先为Hero的name属性,增加setter和getter
通过反射机制调用Hero的setName
package charactor; public class Hero { public String name; public float hp; public int damage; public int id; public String getName() { return name; } public void setName(String name) { this.name = name; } public Hero(){ } public Hero(String string) { name =string; } @Override public String toString() { return "Hero [name=" + name + "]"; } public boolean isDead() { // TODO Auto-generated method stub return false; } public void attackHero(Hero h2) { // TODO Auto-generated method stub } }
package reflection; import java.lang.reflect.Method; import charactor.Hero; public class TestReflection { public static void main(String[] args) { Hero h = new Hero(); try { // 获取这个名字叫做setName,参数类型是String的方法 Method m = h.getClass().getMethod("setName", String.class); // 对h对象,调用这个方法 m.invoke(h, "盖伦"); // 使用传统的方式,调用getName方法 System.out.println(h.getName()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
步骤 2 :

练习-调用方法

Or  姿势不对,事倍功半! 点击查看做练习的正确姿势
继续上一个练习 练习-通过配置文件获取对象,把hero.config改动成为支持如下格式:

charactor.APHero
garen
charactor.ADHero
teemo


首先根据这个配置文件,使用反射实例化出两个英雄出来。
然后通过反射给这两个英雄设置名称,接着再通过反射,调用第一个英雄的attackHero方法,攻击第二个英雄
package charactor; public class Hero { public String name; public float hp; public int damage; public int id; public String getName() { return name; } public void setName(String name) { this.name = name; } public Hero(){ } public Hero(String string) { name =string; } @Override public String toString() { return "Hero [name=" + name + "]"; } public boolean isDead() { // TODO Auto-generated method stub return false; } public void attackHero(Hero h2) { System.out.println(this.name+ " 正在攻击 " + h2.getName()); } }
package charactor; public class APHero extends Hero { public void magicAttack() { System.out.println("进行魔法攻击"); } }
package charactor; public class ADHero extends Hero { public void physicAttack() { System.out.println("进行物理攻击"); } }
步骤 3 :

答案-调用方法

在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
package reflection; import java.io.File; import java.io.FileReader; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import charactor.Hero; public class TestReflection { public static void main(String[] args) throws InterruptedException { File f = new File("E:/project/j2se/hero.config"); try (FileReader fr = new FileReader(f)) { String fileContent = null; char[] all = new char[(int) f.length()]; fr.read(all); fileContent = new String(all); String[] cs = fileContent.split("\r\n"); String hero1className = cs[0]; String hero1Name = cs[1]; String hero2className = cs[2]; String hero2Name = cs[3]; //根据反射,获取hero1,并且给hero1的name字段赋值 Class hero1Class = Class.forName(hero1className); Constructor hero1Constructor = hero1Class.getConstructor(); Object hero1 = hero1Constructor.newInstance(); Field hero1NameField = hero1Class.getField("name"); hero1NameField.set(hero1, hero1Name); //根据反射,获取hero2,并且给hero2的name字段赋值 Class hero2Class = Class.forName(hero2className); Constructor hero2Constructor = hero2Class.getConstructor(); Object hero2 = hero2Constructor.newInstance(); Field hero2NameField = hero2Class.getField("name"); hero2NameField.set(hero2, hero2Name); //根据反射,获取attackHero方法,并且调用hero1的这个方法,参数是hero2 Method attackHeroMethod = hero1Class.getMethod("attackHero", Hero.class); attackHeroMethod.invoke(hero1, hero2); } catch (Exception e) { e.printStackTrace(); } } }


HOW2J公众号,关注后实时获知布最新的教程和优惠活动,谢谢。


问答区域    
2017-12-15 求教
二饼
大大 在这个例子中 我知道是子类hero 调用这个方法 因为上面明确的new出来了 但是在后面的项目中 在父类中使用反射机制的时候 使用this来代替这个h 可是到底是怎么知道是哪个子类在调用呢 this为什么可以代表创建出相应的子类对象呢 一直很困惑 求解释 谢谢谢谢








答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2017-11-23 请问下为什么我用getDeclaredField("name")就会报错,getField("name")就不会
120326hjj



百度了下说,getDeclaredField是可以获取一个类本身的所有字段.,getField只能获取类及其父类的public 字段.,问题我是直接访问的Hero这个父类,并且name是public,百思不得其解
Class pc1 = Class.forName(hero1ClassName);
			Constructor c1 = pc1.getConstructor();
			Object h1 = c1.newInstance();
			Field hero1NameField = pc1.getDeclaredField("name");
			hero1NameField.set(h1, hero1Name);
java.lang.NoSuchFieldException: name
	at java.lang.Class.getDeclaredField(Class.java:2070)
	at reflection.TestReflection.main(TestReflection.java:33)


2 个答案

mdls 答案时间:2017-12-23
作者在上一章结尾补充了 getField和getDeclaredField的区别 这两个方法都是用于获取字段 getField 只能获取public的,包括从父类继承来的字段。 getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。 (注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))

extremeways 答案时间:2017-12-20
是对象类型的原因吧,你改成Hero类型试试; Class pc1 = Class.forName(hero1ClassName); Constructor c1 = pc1.getConstructor(); Hero h1 = (Hero)c1.newInstance(); Field hero1NameField = pc1.getDeclaredField("name"); hero1NameField.set(h1, hero1Name);




答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2017-09-14 getMethod("setName", String.class);报错
2017-08-16 步骤 2 中 ADHero 与 APHero 中 attackHero(Hero hero) 方法不存在
2017-08-01 反射怎么复杂,为什么要用呢?
2017-03-31 1."\r\n"截取的字符串出错,改成"\n"就正常了。2.charactor.ADHero和charactor.APHero没有这两个类啊,
2016-06-30 上节课 网页挂了
2016-04-05 getMethod("setName", String.class);




提问之前请登陆
关于 JAVA 高级-反射机制-调用方法 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 389538688
站长会在每个工作日早上尽量回答提问(如果有漏掉没有回答的,请进群提醒一下)
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
站长是玻璃心,提问的时候请语气温柔些 kiss~
截止2017-5-19日累计提问 1638个,站长回答了 1546个
截止2017-8-15日累计提问 2788个,站长回答了 2544个

上传截图