【JavaSE】反射机制(工具思想)

话不多说,先上代码。
先来一个接口

public interface IDoSomething {
	//简单定义一个方法
	void doSomething(String message);
}

然后,实现两个有关于这个接口的实现类:

public class Teddy implements IDoSomething {
	//实现该接口,必然要实现该接口所定义的方法;
	public Teddy() {
	}
	
	@Override
	public void doSomething(String message) {
	//这里我们仅仅简单实现一下
		System.out.println("我是渣男,我怕谁!" + message);
	}

}

public class Rascal implements IDoSomething {
	//实现该接口,必然要实现该接口所定义的方法;
	public Rascal() {
	}

	@Override
	public void doSomething(String message) {
	//这里我们仅仅简单实现一下
		System.out.println("不接受!!不拒绝!!!" + message);
	}
	
}

最后,再写一个SomeRakishClass 类,

public class SomeRakishClass {
	//定义一个接口类型的成员,
	private IDoSomething doSomething;
	
	static {
		//这里的 PropertiesParser是我自己曾经做过的一个properties文件解析工具,
		//现在直接使用该工具,代码写起来很爽。 
		//properties文件解析工具 请看博文连接:
		//    https://blog.csdn.net/weixin_44836233/article/details/103111697

		PropertiesParser pp = new PropertiesParser();
		//需要注意的是文件的路径, 一个“/”是把src当做根目录。
		pp.loadProperties("/class.properties");
	}
	
	public SomeRakishClass() {
	}
	
	public void doSome() {
 //因为我的工具中的Map是static,是单例的,所以不论我怎么new,都是对同一个Map进行操作的
		String className = new PropertiesParser().getValue("class");
		try {
		//以下则是反射机制:
		
			Class<?> klass = Class.forName(className);
			Object obj = klass.newInstance();
			if (!(obj instanceof IDoSomething)) {
				return;
			}
			doSomething = (IDoSomething) obj;
			
			//因为定义了一个接口类型的成员,那么我们一定可以调用该接口所定义的方法
			doSomething.doSomething("我是一个乖宝宝!");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	
}

因为SomeRakishClass 类用到了properties文件,所以我们要建立一个properties文件:
在这里插入图片描述

用Test类测试一下:

public class Test {

	public static void main(String[] args) {
		new SomeRakishClass().doSome();
	}

}

上述代码的执行结果很简单:
在这里插入图片描述
然而,若果我们只修改properties文件,而不修改源代码,再看执行结果:
在这里插入图片描述
在这里插入图片描述
显而易见,这里的结果发生了更改。
由此我们可以想象,假如把SomeRakishClass 类和接口,打包,以后让别人用,那么,只要我们以后实现了该接口,把properties文件配置好,那么我们根本不用去更改源代码,这在c语言里,是想都不敢想的啊。这就是反射机制。
上述其实只用到了反射机制的一个Class.forName();其实,我们还可以更改成员的值,执行类里面的方法……
来看下面的代码:

public static void main(String[] args) {
	//这里同样用到了PropertiesParser工具:
	//配置文件,进行了修改,改成了一个复数相加的类,具体代码见最后。
		PropertiesParser property = new PropertiesParser();
		property.loadProperties("/class.properties");
		String className = property.getValue("class");
		System.out.println(className);
		try {
			Class<?> klass = Class.forName(className);
			Object obj = klass.newInstance();
			System.out.println("obj :" + obj.getClass());
			
			Constructor<?> constructor = klass
									.getConstructor(double.class,double.class);
			Object object = constructor.newInstance(3.14,5.36);
			System.out.println(object + "  obj :" + obj.getClass());
			
			Method method = klass.getMethod("add", klass);
			//这里getMethod()方法是指找到该方法,并用method指向它
			//其中的两个参数分别是:
			//前面是指klass类中的方法名称,后面是指这个类的这个方法的参数类型
			Object ob = method.invoke(obj, object);
			//invoke()方法是指执行method所指向的方法
			//其中的两个参数分别是:
			//前面是指要执行的对象,后面是指符合该方法的参数类型的值。
			System.out.println(ob + "  obj : " + obj.getClass());
			
			Field field = klass.getDeclaredField("vir");
			field.setAccessible(true);
			field.set(object, 123);
			System.out.println(object);
			
			Field virField = klass.getDeclaredField("vir");
			String fileName = virField.getName();
			String name = "set" + fileName.substring(0, 1)
						.toUpperCase() + fileName.substring(1);
			Method m = klass.getDeclaredMethod(name,virField.getType());
			m.invoke(object, 1.0);
			System.out.println(object);
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}

结果如下:
在这里插入图片描述
由此可见,反射机制的强大!!!

这里是复数类的相关代码:

public class Complex {
	private double real;
	private double vir;
	
	public Complex() {
	}

	public Complex(double real) {
		this.real = real;
	}

	public Complex(double real, double vir) {
		this.real = real;
		this.vir = vir;
	}
	
	public Complex(Complex complex) {
		this.real = complex.real;
		this.vir = complex.vir;
	}

	public double getReal() {
		return real;
	}

	public void setReal(double real) {
		this.real = real;
	}

	public double getVir() {
		return vir;
	}

	public void setVir(double vir) {
		this.vir = vir;
	}

	// 四则运算的实现
	// 先实现加法;根据需求分析可知:加法需要实现两种:
	// c = a + b和
	// a += b
	// 先实现a += b
	public Complex add(Complex other) {
		this.real += other.real;
		this.vir += other.vir;
		
		return this;
	}
	
	// 再实现c = a + b
	public static Complex add(Complex one, Complex other) {
		return new Complex(one).add(other);
	}

	/*
		Complex result = new Complex();
		
		result.real = one.real + other.real;
		result.vir = one.vir + other.vir;
		
		return result;
		
		c = -b;
		b的值在执行完上述语句后,当然不能更改!
	 */
	
	private static Complex opposite(Complex one) {
		return new Complex(-one.real, -one.vir);
	}
	
	public Complex sub(Complex other) {
		return add(opposite(other));
	}
	
	public static Complex sub(Complex one, Complex other) {
		return new Complex(one).sub(other);
	}

	// 1/(a+bi)
	// (a-bi)/((a+bi)(a-bi))
	// (a-bi)/(a*a + b*b)
	// 实部:a/(a*a + b*b);虚部:-b/(a*a + b*b)
	private static Complex reciprocal(Complex c) {
		double mod = c.real*c.real + c.vir*c.vir;
		
		return Math.abs(mod) <= 1e-6 ? null : new Complex(c.real / mod, -c.vir / mod);
	}
	
	// a *= b
	// (a1+b1i) * (a2+b2i) = (a1*a2 - b1*b2) + (a1*b2 + a2*b1)i
	public Complex mul(Complex other) {
		double real = this.real;
		this.real = real * other.real - this.vir *other.vir;
		this.vir = real * other.vir + vir * other.real;
		
		return this;
	}
	
	// c = a*b
	public static Complex mul(Complex one, Complex other) {
		return new Complex(one).mul(other);
	}
	
	// a /= b
	public Complex div(Complex other) {
		Complex reciprocal = Complex.reciprocal(other);
		return reciprocal == null ? null : this.mul(reciprocal);
	}
	
	// c = a / b
	public static Complex div(Complex one, Complex other) {
		return new Complex(one).div(other);
	}
	
	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (this == obj) {
			return true;
		}
		if (obj.getClass() != this.getClass()) {
			return false;
		}
		
		Complex c = (Complex) obj;
		
		return Math.abs(c.real - this.real) < 1e-6 && Math.abs(c.vir - this.vir) < 1e-6;
	}

	@Override
	public String toString() {
		return "(" + real + ", " + vir + ")";
	}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值