how2j.cn


工具版本兼容问题
通过反射机制,调用一个对象的方法


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

首先为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 :

练习-调用方法

edit 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 :

答案-调用方法

edit
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
查看本答案会花费4个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法
查看本答案会花费4个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法
账号未激活 账号未激活,功能受限。 请点击激活
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公众号,关注后实时获知布最新的教程和优惠活动,谢谢。


问答区域    
2019-01-10 交作业
阿兔



Hero 的attack方法我用了一个能实际削减血量的站长在多线程章节的方法。因此给取出来的ADHero APHero都赋值了。 运行结果是gareen 正在攻击 teemo, teemo的血变成了 50 还可以进一步改进写成多线程的方法,创建新线程 new Thread 调用isDead方法 public void run(){ while(!adHero.isDead()) { m.invoke(adHero, apHero);} } 使得gareen 一直攻击 teemo到血量归零
package Charactor.Hero;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;

public class GetReflectionTest {
	APHero aph = new APHero();
	ADHero adh = new ADHero();
	
	public static void main(String[] args) {
	File f = new File("/Users/yuqian/Desktop/hero.config.txt");
	
	try(FileOutputStream fos = new FileOutputStream(f);DataOutputStream dos = new DataOutputStream(fos);){
		dos.writeUTF("Charactor.Hero.ADHero");
		dos.writeUTF("gareen");
		dos.writeUTF("Charactor.Hero.APHero");
		dos.writeUTF("teemo");
	}catch (IOException e){
		e.printStackTrace();
	}	
	try(FileInputStream fis = new FileInputStream(f);DataInputStream dis = new DataInputStream(fis);){
		String adHeroClass = dis.readUTF();
		String adHeroName = dis.readUTF();
		String apHeroClass = dis.readUTF();
		String apHeroName = dis.readUTF();
		try {
			ADHero adHero = (ADHero) Class.forName(adHeroClass).getConstructor().newInstance();
			APHero apHero = (APHero) Class.forName(apHeroClass).getConstructor().newInstance();
			adHero.name = adHeroName;
			apHero.name = apHeroName;
			adHero.hp = 100;
			apHero.hp = 100;
			adHero.damage = 50;
			apHero.damage = 50;
			Method m = adHero.getClass().getMethod("attackHero", Hero.class);
			m.invoke(adHero, apHero);
			
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}catch(IOException e) {
		e.printStackTrace();
	}	
	}
}

package Charactor.Hero;

public class Hero {
    public String name;
    public float hp;
    public int damage;
    int totalTime = 3;
   	public int id;
 
    public Hero() {
 
    }
 
    public Hero(String name) {
        this.name = name;
        }

    public Hero(String name, float hp, int damage) {
        this.name = name;
        this.hp = hp;
        this.damage = damage;
        }
 
    public void setName(String name) {
    	this.name = name;
    }
    public String getName() {
    	return name;
    }
    
    public void attackHero(Hero h) {
        try {
            // 为了表示攻击需要时间,每次攻击暂停1000毫秒
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        h.hp -= damage;
        System.out.format("%s 正在攻击 %s, %s的血变成了 %.0f%n", name, h.name, h.name, h.hp);
 
        if (h.isDead())
            System.out.println(h.name + "死了!");
    }
 
    public boolean isDead() {
        return 0 >= hp ? true : false;
    }
 
   
 
    public void adugen() {
        while (true) {
            for (int i = 0; i < totalTime; i++) {
                System.out.printf("波动拳第%d发%n", i + 1);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
 
            System.out.println("开始为时5秒的充能");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
 
    }
    public static void main(String[] args) {
        Hero h = new Hero();
        h.name = "红仔";
 
        h.adugen();
 
    }
 
}





回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2019-01-04 对于没有参数的方法怎么用?
kgbofcccp
对于没有参数的方法应该怎么用?




1 个答案

yiyang 答案时间:2019-01-13
m.invoke(h);不填第二个参数



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2018-09-17 交作业
2018-09-06 交作业
2018-08-21 如何识别中文?
2018-08-02 交作业
2018-03-02 请问练习题 反射得到的两个对象都没有强制转换 Obejct对象是没有要用的name属性和attackHero方法的,为什么还能执行成功呢?
2018-02-21 对比了两个获取方法的参数,这个是应该怎么选择?
2017-12-15 求教
2017-11-23 请问下为什么我用getDeclaredField("name")就会报错,getField("name")就不会
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群交流: 984886441
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: http://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图