Java基础10(反射)

                                      Java基础10(反射)

1 什么是反射

官方解释:反射(reflection)技术通常被用来检测和改变应用程序在 Java 虚拟机中的行为表现。它是一个相对而言比较高级的技术,反射是一种强有力的技术特性,因此可以使得应用程序突破一些藩篱,执行一些常规手段无法企及的目的。通俗理解就是:反射是一种非常规手段,能在程序运行时修改程序的行为,使用有风险,需谨慎。反射可以被视为动态语言,反射机制允许程序再执行期间借助反射的API来获取任意类的内部信息。

反射的功能:①在运行时判断对象所属类②在运行时通过构造器获取对象的实例③在运行时获取类的成员变量(属性),方法等④通过反射获取类中的成员属性,方法。

反射涉及要的一些类

描述

         java.lang.Class

反射的源头,Class类的实例表示正在运行的java应用程序的类和接口

      java.lang.reflect.Field

提供有关类或接口的属性信息及动态范围权限,可以理解为封装了反射类属性的类

    java.lang.reflect.Method

提供有关类或接口的单独某个方法的信息

java.lang.reflect.Constructor

提供类的单个构造方法的信息以及他的访问权限

2 理解Class类,实例化Class类实例

Class类是反射的源头。注意要和类的概念区分开来,Class类是一个实实在在的类,在 java.lang下有个Class.java的文件和我们自己定义的类一样,Class对象就是这个类的实例。Class类是继承了Object的特殊类,他的内部可以记录类的成员,接口等信息,可以理解为Class是一个用来表示类的类。

java是运行在JVM上的,我们写好的类经过编译器编译后会生成.class文件。在运行期间,当我们要实例化一个类时,会先在内存中查看是否存在这个类,存在的话就直接创建类实例,如果没有的话就会就会去加载这个类,当加载一个类或者类加载器的defineClass()被JVM调用,便会为这个类产生一个class对象(一个Class类的实例),用来表示这个类,该类所有实例都共同拥有这个Class对象,而且是唯一的。

在java中,类是用来描述信息的,写明了有哪些内部的属性及接口,相当于定义了一套规则。Class对象被用来对类的情况进行表述的一个实例,类的实例表征,可以理解为对类的图形化,这样JVM才看的懂,看做模板。类的实例化对象,就是通过模版,开辟出的一块内存进行实际的使用。

创建Class类实例:

(1)调用运行时类本身的.class属性。如Class clazz = String.class

(2)通过运行时类的对象。如:Person p = new Person(); Class c = p.getClass();

(3)通过Class类的静态方法forName(String className)。 如: Class.forName(“包名.类名”)

(4)通过JVM类加载器。如:ClassLoader c = this.getClass().getClassLoader(); Class clazz = c.getClass();

Object中有个getClass()方法获得运行时类。

3 运行时创建类(Class)的对象,并获得类的完整结构

public class TestReflect {
	@Test
	public void test() throws Exception {
		Class clazz = Class.forName("month201906.day13.Person");
		Person p = (Person) clazz.newInstance();
		// 获得包名
		Package package1 = clazz.getPackage();
		String packName = package1.getName();
		System.out.println(packName);

		// 获得类名
		System.out.println(clazz.getSimpleName());

		// 获得属性名及其权限修饰符
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			System.out.println(Modifier.toString(field.getModifiers()) + "---" + field.getName());
		}

		// 获得方法名及其权限修饰符
		Method[] methods = clazz.getDeclaredMethods();
		for (Method method : methods) {
			System.out.println(Modifier.toString(method.getModifiers()) + "---" + method.getName());
		}

		// 获得父类
		System.out.println(clazz.getSuperclass());

		// 获得注解
		Annotation[] annotations = clazz.getAnnotations();
		for (Annotation annotation : annotations) {
			System.out.println(annotation);
		}

		// 获取接口
		Class[] interfaces = clazz.getInterfaces();
		for (Class inter : interfaces) {
			System.out.println(inter);
		}
	}
}

@Target({ TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE })
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
	String name() default "zhujie";
}

class Work {
	String worker;

	public void doWorker() {
		System.out.println("工作");
	}
}

@MyAnnotation(name = "注解")
class Person extends Work implements Serializable {
	public String name;
	int age;
	private String gender;
	protected int score;

	public Person() {
		System.out.println("无参构造");
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public Person(String name, int age, String gender, int score) {
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.score = score;
	}

	private String Method1(String name, int age, String gender, int score) {
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.score = score;
		return name;
	}

	public String Method2() {
		return "Person [name=" + name + ", age=" + age + ", gender=" + gender + ", score=" + score + "]";
	}

	public static void Method3() {
		System.out.println("Method3 static");
	}

	private void Method4() {
		System.out.println("Method4 private");
	}

	protected void Method5() {
		System.out.println("Method5 protected");
	}

	void Method6() {
		System.out.println("Method6 null");
	}

	public void Method7() {
		System.out.println("Method6 public");
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", gender=" + gender + ", score=" + score + "]";
	}

}

 

4 通过反射获取类的指定属性、方法、构造器

public class TestReflect {
	@Test
	public void test1() throws Exception{
		Class clazz = Class.forName("month201906.day13.Person");
		Person p = (Person) clazz.newInstance();
		
		//获取指定构造器
		System.out.println(clazz.getDeclaredConstructor());
		//有参构造
		Constructor<Person> con = clazz.getDeclaredConstructor(String.class,int.class,String.class,int.class);
		Person newInstance = con.newInstance("小明",18,"男",1000);
		System.out.println(newInstance);
				
		//获取指定属性
		Field name = clazz.getDeclaredField("name");
		//调用属性
		name.set(p, "小红");
		System.out.println(p);
		Field gender = clazz.getDeclaredField("gender");
		gender.setAccessible(true);
		gender.set(p, "女");
		System.out.println(p);
		
		//获取指定方法
		Method method1 = clazz.getDeclaredMethod("Method1", String.class,int.class,String.class,int.class);
		//调用方法
		method1.setAccessible(true);
		method1.invoke(p, "张三",20,"男",5000);
		System.out.println(p);
		//调用方法
		Method method4 = clazz.getDeclaredMethod("Method4");
		method4.setAccessible(true);
		method4.invoke(p);
		
	}
	
}

5 动态代理

public class TestDynamicProxy {
	public static void main(String[] args) {
		RealMothod1 real = new RealMothod1();
		MyInvocationHandler inv1 = new MyInvocationHandler(real);
		// 获取代理对象
		pubMothod1 obj = (pubMothod1) inv1.getObj();
		obj.action();

		RealMothod2 r = new RealMothod2();
		MyInvocationHandler inv2 = new MyInvocationHandler(r);
		// 获取代理对象
		pubMothod2 pub = (pubMothod2) inv2.getObj();
		pub.show();
	}
}

// 公共方法
interface pubMothod1 {
	void action();
}

interface pubMothod2 {
	void show();
}

// 被代理类1
class RealMothod1 implements pubMothod1 {
	@Override
	public void action() {
		System.out.println("被代理类1号");
	}

}

// 被代理类2
class RealMothod2 implements pubMothod2 {
	@Override
	public void show() {
		System.out.println("被代理类2号");
	}
}

// 代理类的处理类   1.创建代理对象 ,2.调用代理对象代理的方法
class MyInvocationHandler implements InvocationHandler {
	// 被代理类的对象的声明,代理被代理类的对象
	Object obj; 
	// 给被代理对象 初始化
	public MyInvocationHandler(Object obj) {
		this.obj = obj;
	}
	// 代理对象 ,代理对象调用重写的那个方法,自动调用invoke
	public Object getObj() {
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("我是invoke");
		// 反射 "被"代理对象的方法
		Object object = method.invoke(obj, args);
		return object;
	}

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值