接口与类型信息_reflect

Interface关键字的一个重要目标就是允许程序员隔离构件,降低耦合性。但是通过类型信息,这种耦合性还是会传递出去,见例子:

1. 定义接口A:

package reflect;

public interface A {	
	void f();
}

2. 实现类B:

package reflect;

public class B implements A {

	@Override
	public void f() {
		System.out.println("public B.f()");
	}
 
	public void g() {
		System.out.println("public B.g()");
	}	
}

3. 客户端代码:

public class InterfaceViolation {
	
	public static void main(String[] args) {
		A a = new B();
		System.out.println(a.getClass().getName());
		if(a instanceof B) {  //客户端程序员可向下转型为指定类型
			B b = (B)a;
			b.g();
		}
	}
}

这种处理是完全合法的,但是增加了代码耦合性。一种解决办法对实现使用包访问权限

4. 实现类C, 限制访问权限:

package reflect;

public class HiddenC {   
	
	public static A makeA() {
		return new C();
	}
}

class C implements A {

	@Override
	public void f() {
		System.out.println("public C.f()");
	}
	
	public void g() {
		System.out.println("public C.g()");
	}
	
	void u() {
		System.out.println("package C.u()");
	}
	
	protected void i() {
		System.out.println("protected C.i()");
	}
	
	private void h() {
		System.out.println("private C.h()");
	}
	
}

5. 受限的客户端代码(在C类的包外部,访问是受限的):

a) 此时仍可通过暴力反射来访问C类的所有方法

package designpattern;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import reflect.A;
import reflect.HiddenC;

public class HiddenImplementation {
	
	public static void main(String[] args) {
		A a = HiddenC.makeA();
		System.out.println(a.getClass().getName());
		a.f();
		//C类位于reflect包,且访问权限为包权限,故此处无法调用
//		if(a instanceof C) {
//			C c = (C)a;
//			c.g();
//		}
		callHiddenMethod(a, "g");   //反射调用不可见的方法
		callHiddenMethod(a, "u");
		callHiddenMethod(a, "i");
		callHiddenMethod(a, "h");
		
	}
	
	static void callHiddenMethod(Object o, String methodName) {
		try {
			Method m = o.getClass().getDeclaredMethod(methodName);
			m.setAccessible(true);   //暴力反射
			m.invoke(o);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	
}




 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值