首页 > 编程语言 >java学习笔记018 反射

java学习笔记018 反射

时间:2022-09-02 18:26:32浏览次数:46  
标签:java String Object 笔记 Class public 018 clazz class

1.java.lang.Class
获取Class对象的四种方式
//1
Class clazz1 = Person.class;
//2
Person p = new Person();
Class clazz2 = p.getClass();
//3	用得多
Class clazz3 = Class.forName("com.cg.Person");
//4
Class clazz4 = 当前类名.class.getClassLoader().loadClass("com.cg.Person")
//四个clazz的地址一致,即为同一个对象

类、接口、数组、基本数据类型、注解、void都可以获取到Class对象
2.理解类的加载过程
类的加载
	java.exe命令将.class文件加载到内存中的过程,加载到内存中的类叫做运行时类,一个运行时类对应一个Class类的对象
	
类的加载过程
	Load		加载	
	Link		链接	将类的二进制数据合并到JRE
	Initialize	初始化

类加载器 ClassLoader
	System ClassLoader 系统类加载器
		//自定义类调用getClassLoader()获得系统类加载器
		ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
	
	Extension ClassLoader 扩展类加载器
		//系统类加载器调用getParent()获得扩展类加载器
		ClassLoader classLoader1 = classLoader.getParent();
		
	BootStap ClassLoader 引导类加载器
		加载核心类库
	
通过类加载器读取.properties文件
	eg:
		ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
		//默认在src路径下
		IputStream is = classLoader.getResourceAsStream("demo.properties");
		Properties pro = new Properties();
		pro.load(is);
		String name = pro.getProperty("name");
3.创建运行时类的对象
	eg:
		Class<Person> clazz = Person.class;
		//内部调用运行时类的空参构造器
		//所以要求有空参构造器且权限足够,一般为public
		//javabean要求提供一个public的空参构造器,便于反射调用对象和子类继承
		Person p = clazz.newInstance();
4.获取运行时类的完整结构
	eg:
		Class clazz = Person.class;
		属性Field
			//此方法获取当前运行时类及其父类中public修饰的属性
			Field[] fields = clazz.getFields();
			//此方法获取当前运行时类中声明的所有属性(不包括从父类继承的属性)
			Field[] fields = clazz.getDeclaredFields();
		
			for(Field f : fields){
				//1权限修饰符
				int modifier = f.getModifiers();
				System.out.println(Modifier.toString(modifier));
				
				//2数据类型
				Class type = f.getType();
				System.out.println(type.getName());
				
				//3变量名
				String fieldName = f.getName();
				
			}
		
		方法Method
			//getMethods()获取当前运行时类及其父类中public修饰的方法
			Method[] methods = clazz.getMethods();
			//getDeclaredMethods()获取当前运行时类中声明的所有方法(不包括从父类继承的方法)
			Method[] methods = clazz.getDeclaredMethods();
			
			for(Method m : methods){
				//1权限修饰符
				int modifier = m.getModifiers();
				System.out.println(Modifier.toString(modifier));
				
				//2返回值类型
				Class returnType = m.getType();
				System.out.println(returnType.getName());
				
				//3方法名
				String methodName = m.getName();
				
				//4参数列表
				Class[] parameterTypes = m.getParameterTypes();
				if(!(parameterTypes == null || parameterTypes.length == 0)){
					for(int i=0; i<parameterTypes.length; i++){
						System.out.println(parameterTypes[i].getName() + " args_" + i);
						if(i < parameterTypes.length-1){
							System.out.println(", ");
						}
						
					}
				}
				
				//5标记方法的注解
					//只能获取RETENTION为RUNTIME的注解
				Annotation[] = annos = m.getAnnotations();
				
				
				//6throws的异常类
				Class[] exceptionTypes = m.getExceptionTypes();
				for(Class e : exceptionTypes){
					System.out.println(e.getName());
				}
			}
			
		构造器 Constructor
			//获取当前运行时类中声明为public的构造器
			Constructor[] constructors = clazz.getConstructors();
			//获取当前运行时类中声明为public的构造器
			Constructor[] constructors = clazz.getConstructors();
			
			Constructor[] constructors = clazz.getDeclaredConstructors();
			
		父类
			Class superclass = clazz.getSuperclass();
			
		带泛型的父类的泛型
			Type superclass = clazz.getGenericSuperclass();
			ParameterizedType paramType = (ParameterizedType) superclass;
			//获取泛型参数
			Type[] actualTypeArguments = paramType.getActualTypeArguments();
			
		接口
			//只包括类自己声明实现的接口
			Class[]	getInterfaces()
			Class[]	getGenericInterfaces()
			
		包
			Package package = clazz.getPackage();
5.调用运行时类的指定结果
属性
	Field	getField(String name)
	Field	getDeclaredField(String name)
	Field[]	getFields()
	Field[]	getDeclaredFields()
			
		eg:
			Class clazz = Person.class;
			Person person = (Person) clazz.newInstance();
			
			Field name = clazz.getField("name");
			name.set(person, "张三");
			String pName = (String) name.get(person);
			
			Field id = clazz.getDeclaredField("id");
			id.setAccessible(true);
			id.set(person, 1001);
			int pId = (int) id.get(person);
	
方法
	getDeclaredMethod(String methodName, Class ... args)
	
	//invoke()的返回值即为调用的方法的返回值
	Object invoke(Object instance, Object ... args)
	静态方法
	Object invoke(Class clazz, Object ... args)
	
	eg:
		Method show = clazz.getDeclaredMethod("show", String.class);
		show.setAccessible(true);
		Object returnVal = show.invoke(person, "helloworld");
	
构造器
	最常用的是newInstance(),其他了解即可
	eg:
		//getDeclaredConstructor(Class ... args);
		Constructor constructor = clazz.getDeclaredConstructor(String.class);
		constructor.setAccessible(true);
		//clazz.newInstance()调空参构造器
		Person person = (Person) constructor.newInstance("helloworld");

6.动态代理

代理模式回顾
	//代理类
	class Server implements Network{
		private Network net;
		public Server(Network net){
			this.net = net;
		}
		@Override
		public void overrideMethod(){
			stepAhead();
			net.overrideMethod();//真实的接口实现类对象
			stepAfter();
		}
	}
	
动态代理
	问题
		如何通过被代理类动态地创建一个代理类及其对象?
		通过代理类调用方法时,如何动态地调用被代理类中的同名方法?

eg:

package com.cg.reflection;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author zhengcg
 * @create {2022}-{09}-{02}-{17:19}
 */
public class DynamicProxyTest {
	public static void main(String[] args) {
		UserNetwork userNetwork = new UserNetwork();
		Network proxy1 = (Network) ProxyFactory.getProxyInstance(userNetwork);
		Upload proxy2 = (Upload) ProxyFactory.getProxyInstance(userNetwork);
		System.out.println(proxy1 == proxy2);   //false
		proxy1.surfInternet();
		String msg = proxy2.uploadFile();
		System.out.println(msg);
	}
}

interface Network{
	void surfInternet();
}
interface Upload{
	String uploadFile();
}

class UserNetwork implements Network, Upload {
	@Override
	public void surfInternet() {
		System.out.println("用户开始网上冲浪");
	}

	@Override
	public String uploadFile() {
		return "用户上传了一些文件";
	}
}

class ProxyFactory{
	public static Object getProxyInstance(Object proxied){
		//返回的代理类在调用接口中的方法时,实际会调用MyInvocationHandler中的方法
		return Proxy.newProxyInstance(proxied.getClass().getClassLoader(),
										proxied.getClass().getInterfaces(),
										new MyInvocationHandler(proxied));
	}
}

class MyInvocationHandler implements InvocationHandler{
	//被代理类
	private final Object proxied;
	public MyInvocationHandler(Object proxied){
		this.proxied = proxied;
	}
	@Override
	//proxy:哪个代理类调用接口中的方法;method:代理类调用了接口中哪个方法;args:传给被调用方法的参数
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//调用被代理类中同名方法,可以做一些前置准备工作和后置收尾工作
		return method.invoke(proxied, args);
	}
}

AOP与动态代理举例

AOP	Aspect Orient Programming	面向切面编程

标签:java,String,Object,笔记,Class,public,018,clazz,class
From: https://www.cnblogs.com/zhengcg/p/16644523.html

相关文章

  • java.lang.reflect.InvocationTargetException
    1.自定义BaseServlet时候,里面的方法应该是重新HttpServlet里的service方法,自己写成dogetdopost了,错误!2.mapper的xml配置文件,查询总数的方法selectTotalCount需要......
  • java实现桌面右下角弹窗效果
    http://www.3qphp.com/java/framework/3542.htmlInfoUtil.javaimportjava.awt.BorderLayout;importjava.awt.Color;importjava.awt.Cursor;importjava.awt.Deskt......
  • 防止JAVA程序重复启动的一个另类解决办法
    http://blog.itpub.net/443058/viewspace-915510/我们项目中有一个后台任务处理程序,是java开发application,用以处理网站提交的一些批量数据文件,因为这些数据文件数据量一......
  • Java 在Word文档中添加艺术字
    艺术字是以普通文字为基础,经过专业的字体设计师艺术加工的变形字体。字体特点符合文字含义、具有美观有趣、易认易识、醒目张扬等特性,是一种有图案意味或装饰意味的字体变......
  • java下载csv乱码问题
    一.问题。用EXCEL打开文件时,总是产生乱码,但是用NOTEPAD++打开时,显示正常。然后,在NOTEPADD++的“格式”工具栏中查了一下文件编码,发现是“以UTF-8格式编码”。二.解决......
  • 【校招VIP】[Java][一本][6分]按照真实的技能点进行业务描述
    关注【校招VIP】公众号,回复【简历】,添加校招顾问微信,即可获取简历指导!本份简历是一位21届一本java同学的简历,简历评分6分。一、学员简历  二、指导意见简历版式问......
  • 【校招VIP】[Java][211][7分]重点展开与java开发有关的项目
    关注【校招VIP】公众号,回复【简历】,添加校招顾问微信,即可获取简历指导!本份简历是一位21届211硕java同学的简历,简历评分7分。一、学员简历  二、指导意见简历版式......
  • 地理空间数据库设计学习笔记(不分章)
    平时成绩40%,期末60%.平时成绩=考勤10%+作业20%+课堂表现作业=作业+实验报告C/S架构是什么?C/S架构,即Client/Server(客户端/服务器)架构,是一个典型的两层架构。通过将任务......
  • Excel笔记
    一、基础部分(1)求和=sum()(2)平均数=avg()(3)总数=count()(4)分类汇总(5)字符串截取取字符串左边1个字符=LEFT(B34,1)字符串拼接=CONCATENATE("张三","李四")#......
  • java 上传读取 excel
    implementationgroup:'org.apache.poi',name:'poi',version:'5.2.2' implementationgroup:'org.apache.poi',name:'poi-ooxml',version:'5.2.2'//exce......