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  姿势不对,事倍功半! 点击查看做练习的正确姿势
继续上一个练习 练习-通过配置文件获取对象,把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公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2022-01-19 练习 - 调用方法
莫諾




继续上一个练习 练习-通过配置文件获取对象,把hero.config改动成为支持如下格式: charactor.APHero garen charactor.ADHero teemo 首先根据这个配置文件,使用反射实例化出两个英雄出来。 然后通过反射给这两个英雄设置名称,接着再通过反射,调用第一个英雄的attackHero方法,攻击第二个英雄
public static void main(String[] args) {
		
		File f = new File("E:/project/j2se/src/reflect/hero.config");
		Hero[] hero2 =  getHeros(f);
		hero2[0].attackHero(hero2[1]);
	}
	public static Hero[] getHeros(File f) {
		
		String[] s0 = readTem(f);
		String[] pClassName = new String[s0.length/2];
		String[] ClassNames = new String[s0.length/2];
		Class[] pClass = new Class[s0.length/2];
		Constructor[] cs = new Constructor[s0.length/2];
		Hero[] h = new Hero[s0.length/2];
		ADHero adh; APHero aph; 
		for (int i = 0; i < s0.length/2; i++) {
			pClassName[i] = s0[i*2];
			ClassNames[i] = s0[i*2 + 1];
		}
		for (int i = 0; i < s0.length/2; i++) {
			try {
				pClass[i] = Class.forName(pClassName[i]);
				// 构造器
				cs[i] = pClass[i].getConstructor();
				// 通过构造器实例化
				if (pClassName[i].equalsIgnoreCase("charactor.ADHero")) {
					adh = (ADHero) cs[i].newInstance();
					for (int j = 0; j < s0.length/2; j++) {
						if (ClassNames[j].equalsIgnoreCase("garen"))
							adh.setName(ClassNames[j]);
					}
					adh.physicAttack();
					h[i] = (Hero)adh;
				}
				if (pClassName[i].equalsIgnoreCase("charactor.APHero")) {
					aph = (APHero) cs[i].newInstance();
					for (int j = 0; j < s0.length/2; j++) {
						if (ClassNames[j].equalsIgnoreCase("teemo"))
							aph.setName(ClassNames[j]);
					}
					aph.magicAttack();
					h[i] = (Hero)aph;
				}
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}		
		return h;
	}

	public static String[] readTem(File f){
        int l = 0;int i = 0;
        try (
                FileReader fr = new FileReader(f);
                BufferedReader br = new BufferedReader(fr);
        ) {
            while (true) {
                String line = br.readLine();
                if (null == line)
                    break;
                l++;
            }
            br.close();
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String[] s0= new String[l];
        try (
                FileReader fr = new FileReader(f);
                BufferedReader br = new BufferedReader(fr);
        ) {
            while (true) {
                String line = br.readLine();
                if (null == line)
                    break;
                s0[i] = line;
                i++;
            }
            br.close();
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return s0;
    }

							


1 个答案

CharlieLong
答案时间:2023-10-18
答案



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





2021-10-27 反射获取各种方法,单参数是如站长代码method.invoke上面是h.attack(h1),那如果方法是attack(Hero h,Hero h1)两个英雄都是参数这样的怎么用什么反射
qaiwo520




反射获取各种方法,上面是h.attack(h1),那如果方法是attack(Hero h,Hero h1)两个英雄都是参数这样的怎么用什么反射
package reflection;

import Hero.Hero;

import java.io.File;
import java.io.FileReader;
import java.io.FilterReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;

public class end {

    public static void main(String[] args) {

        File file = new File("C:/Users/Administrator/Desktop/hero.config");

        try (FileReader fr = new FileReader(file)) {
            String classname = null;
            char[] all = new char[(int) file.length()];
            fr.read(all);
            String cs = null;
            cs = new String(all);
            String[] sc = cs.split("\r\n");

            String classname1 = sc[0];
            String classname2 = sc[1];
            String name1 = sc[2];
            String name2 = sc[3];
            int HP1 = Integer.parseInt(sc[4]);
            int HP2 = Integer.parseInt(sc[5]);
            int damage1 = Integer.parseInt(sc[6]);
            int damage2 = Integer.parseInt(sc[7]);
//

            Class c = Class.forName(classname1);
            Constructor con = c.getConstructor();
            Object h = con.newInstance();
            Field H = h.getClass().getField("HP");
            H.set(h, HP1);
            Field n = h.getClass().getField("name");
            n.set(h, name1);
            Field d = h.getClass().getField("damage");
            d.set(h, damage1);

            Class c1 = Class.forName(classname2);
            Constructor con1 = c1.getConstructor();
            Object h1 = con1.newInstance();
            Field H1 = h1.getClass().getField("HP");
            H1.set(h1, HP2);
            Field n1 = h1.getClass().getField("name");
            n1.set(h1, name2);
            Field d1 = h1.getClass().getField("damage");
            d1.set(h1, damage2);

            Method attackHeroMethod = c.getMethod("attackHero", Hero.class);
            attackHeroMethod.invoke(h, h1);
            }catch (Exception e){
            e.printStackTrace();

        }
    }

 }


							





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





2020-06-20 练习
2020-05-04 自己写的答案,欢迎大家指正
2020-02-04 把获取对象和调用方法都提取成,功能方法.这样main中代码就很清晰了


提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 16 条以前的提问,请 点击查看

提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 JAVA 高级-反射机制-调用方法 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 578362961
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图