学习笔记--Java反射机制

1.“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl、Python、Ruby是动态语言,C++、Java、C#不是动态语言,但是Java有着一个非常突出的动态相关机制,Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的class。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造,并生成其对象实体,或对其属性赋值、或调用其里面的方法。

2.Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态地获取信息以及动态调用对象的方法的功能Java语言的反射机制。【简单来说,反射机制就是将类的各个组成部分(属性、方法、构造器)封装为其它对象。】

3.反射提供的功能有:①在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。②反编译:.class–>.java。③通过反射机制访问Java对像的属性、方法、构造方法、注解等。

4.反射的相关类
java.lang.Class 类
java.lang.reflect.Constructor 构造方法
java.lang.reflect.Field 成员属性
java.lang.reflect.Method 成员方法
java.lang.reflect.Modifier 修饰符

5.Java类加载的三个阶段
①源代码(source)—经过编译器编译后生成的.class字节码文件。
②类加载(class)—.class字节码文件经过类加载器classloader加载到虚拟机内存,类加载器解析.class文件生成Class类型的对象。
③运行时(runtime)—newInstance()根据Java类型生成对象。

图解:
在这里插入图片描述
6.代码示例

package com.cyl.reflect;

public class User {
	private String name;
	public Integer age;
	public String address;
	Boolean flag;
	protected Long id;
	
	public static Integer a = 100;
	public final static Integer b = 200;

	public User() {
		System.out.println("new User()");
	}
	
	private User(Boolean flag) {
		this.flag = flag;
		System.out.println("new User(flag)");
	}

	User(String name) {
		this.name = name;
		System.out.println("new User(name)");
	}

	public User(String name, Integer age) {
		this.name = name;
		this.age = age;
		System.out.println("new User(name,age)");
	}

	public String say(String msg) {
		System.out.println(msg);
		return msg;
	}

	@Deprecated
	public void show() {
		System.out.println("show time...");
	}

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

	void method2() {
		System.out.println("method2...");
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Boolean getFlag() {
		return flag;
	}

	public void setFlag(Boolean flag) {
		this.flag = flag;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + ", flag=" + flag + ", id=" + id + "]";
	}
}

package com.cyl.reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class ReflectDemo {

	public static void main(String[] args)
			throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		// Class对象获取方式①源代码阶段
		Class<?> class1 = Class.forName("com.cyl.reflect.User");
		// Class对象获取方式②Class对象阶段
		Class<User> class2 = User.class;
		// Class对象获取方式③对象阶段
		Class<? extends User> class3 = new User().getClass();
		System.out.print(class1 == class2 && class2 == class3);// true
		System.out.println();
		System.out.println(class1.getName());// com.cyl.reflect.User 获取完全限定类名
		System.out.println(class1.getSimpleName());// User 获取类名
		System.out.println("----------");

		// 构造方法--start
		// 获取公有的(public)构造方法
		Constructor<?> constructor = class1.getConstructor();
		Constructor<?> constructor2 = class1.getConstructor(String.class, Integer.class);
		Constructor<?>[] constructors = class1.getConstructors();
		// 获取构造方法(忽略修饰符)
		Constructor<?> declaredConstructor = class1.getDeclaredConstructor();
		Constructor<?> declaredConstructor2 = class1.getDeclaredConstructor(String.class);
		Constructor<?> declaredConstructor3 = class1.getDeclaredConstructor(Boolean.class);
		Constructor<?>[] declaredConstructors = class1.getDeclaredConstructors();
		
		//打破访问权限
		declaredConstructor3.setAccessible(true);
		
		//1--public   2--private  4--protected  0--无修饰
		int modifiers = declaredConstructor.getModifiers();
		System.out.println(modifiers);
		
		//调用构造方法
		Object newInstance = declaredConstructor.newInstance();
		Object newInstance2 = declaredConstructor2.newInstance("lucy");
		Object newInstance3 = declaredConstructor3.newInstance(true);
		System.out.println(newInstance3);//User [name=null, age=null, flag=true, id=null]
		// 构造方法--end
		
		System.out.println("----------");

		// 成员变量--start
		// 根据属性名获取公有的(public)属性对象,若‘非公有’或‘属性名不存在’报java.lang.NoSuchFieldException;
		// Field nameField = class1.getField("name");//java.lang.NoSuchFieldException
		// Field name2Field = class1.getField("name2");//java.lang.NoSuchFieldException
		Field ageField = class1.getField("age");
		System.out.println(ageField);// public java.lang.Integer com.cyl.reflect.User.age
		// 获取所有公有的(public)属性对象
		Field[] fields = class1.getFields();
		System.out.println(Arrays.asList(fields));// [public java.lang.Integer com.cyl.reflect.User.age, public
													// java.lang.String com.cyl.reflect.User.address]
		// 根据属性名获取属性对象(忽略修饰符)
		Field nameDeclaredField = class1.getDeclaredField("name");
		System.out.println(nameDeclaredField);
		// 获取所有属性对象(忽略修饰符)
		Field[] declaredFields = class1.getDeclaredFields();
		System.out.println(Arrays.asList(declaredFields));
		
		for (Field field:declaredFields) {
			//成员属性修饰符--类型--名称
			System.out.println(field.getModifiers()+"--"+field.getType()+"--"+field.getName());
		}
		System.out.println();
		
		//打破访问权限
		nameDeclaredField.setAccessible(true);
		//给newInstance3里面的name属性赋值tom
		nameDeclaredField.set(newInstance3, "tom");
		//给newInstance3里面的age属性赋值18
		ageField.set(newInstance3, 18);
		System.out.println(newInstance3);//User [name=tom, age=18, flag=true, id=null]
			
		// 成员变量--end

		System.out.println("----------");

		// 成员方法--start
		// 获取公有的(public)成员方法
		Method method1 = class1.getMethod("show");
		Method method2 = class1.getMethod("say", String.class);
		Method[] methods = class1.getMethods();
		// 获取成员方法(忽略修饰符)
		Method declaredMethod = class1.getDeclaredMethod("method1");
		Method[] declaredMethods = class1.getDeclaredMethods();
		
		for (Method method : declaredMethods) {
			//成员方法修饰符--返回类型--方法名称--参数个数
			System.out.println(method.getModifiers()+"--"+method.getReturnType()+"--"+method.getName()+"--"+"--"+method.getParameterCount());
		}
		System.out.println();
		
		//调用newInstance3里的方法
		Object invoke = method1.invoke(newInstance3);
		System.out.println(invoke);//返回值 null
		Object invoke2 = method2.invoke(newInstance3, "hello");
		System.out.println(invoke2);//返回值 hello
		
		//打破private访问权限
		declaredMethod.setAccessible(true);
		declaredMethod.invoke(newInstance3);
		
		//获取方法上注解
		Method show = class1.getDeclaredMethod("show");//@Deprecated
		Annotation[] annotations = show.getAnnotations();
		for(Annotation annotation:annotations) {
			System.out.println(annotation.annotationType());//interface java.lang.Deprecated
		}
		
		// 成员方法--end
		

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值