类加载、反射机制总结

本文详细介绍了Java中的类加载过程,包括加载、链接、初始化、使用和卸载阶段。接着深入探讨了反射机制,从获取类对象、反射创建对象、访问构造器、成员变量和方法对象等方面进行了阐述,并讨论了反射的作用,如动态操作类和破坏封装性。
摘要由CSDN通过智能技术生成

1.类加载

类(文件 Hello.class)–>JVM 加载到内存的过程。

1.1类加载的顺序

1.1.1 加载: 加载class文件

内存中创建一个特殊对象Class

Car c = new Car();
		
System.out.println(c.getClass());
System.out.println(Car.class);

Class<?> clazz = Class.forName("com.dyit.classloader.Car");

何时加载class文件:

  1. new Car();
  2. Class.forName(“包.类”);

来加载Car.class: 类加载器

  1. Bootstrap 类加载器
  2. Extension 类加载器
  3. Application 类加载器

app–>继承—>ext–>继承–>-bootstrap

双亲委托机制:
  Car.class--->加载(App)-->Ext(检查)-->Bootstrap
  • /*
     * 类加载器之间关系 
     */
    System.out.println(clazz.getClassLoader());
    System.out.println(clazz.getClassLoader().getParent());
    System.out.println(clazz.getClassLoader().getParent().getParent());
    
    

1.1.2 链接: class文件内容合法

  • 验证: 0xCAFEBABE
  • 准备: 类变量(static)分配内存空间-方法区,初始化
class  A{
  static int x = 3;   --->分配static内存   x=0;

}

  • 解析

1.1.3 初始化,对类中的定义的属性进行初始化

x = 3;

1.1.4 使用

1.1.5 卸载

2.反射

2.1 反射概述

(反射的基本作用,关键?)

  • 反射是在运行时获取类的字节码文件对象:然后可以解析类中的全部成分
  • 核心思想和关键:得到编译以后的class文件

2.2 反射获取类对象

之前: Car c = new Car( );
现在 : clazz.newInstance() —>创建对象

2.2.1 创建对象的四种方式

方式举例
new关键字new Car();
clone(Object 的方法)c.clone()
(反)序列化(Serialable)ObjectInputStream/ObjectOutputStream
反射Class对象clazz.newInstance();

2.3 反射获取构造器对象

getDeclaredConstructors()取得全部构造器,不分public还是private,存到集合里
getDeclaredConstructor()取得单个构造器

反射得到的构造器可以做什么?

  • 还是创建对象
  • 如果是非public的构造器,需要打开权限(暴力反射),然后创建对象:
    setAccessible(boolean)
    反射可以破坏封装性,私有的也可以执行。
/*
 * 利用反射技术获取无参和有参构造器
 */
        //第一步:获取类对象
		Class b = Book.class;
        //第二步:提取类中的全部构造器对象
		Constructor[] constructors = b.getDeclaredConstructors();
		//第三部:遍历构造器
		for (Constructor constructor : constructors) {

			System.out.println("构造器名称" + constructor.getName() + "构造器参数数量" + constructor.getParameterCount());
   
		}
			/*
			 * 调用无参和有参构造器实例化对象返回
			 */
			//无参
			Book book = (Book) constructors[1].newInstance();
			System.out.println(book);
			//有参
			Book book2 = (Book) constructors[0].newInstance(010,"asdd","asd","asdasd","dasdasd",120.0,new Date());
            System.out.println(book2);

2.4 反射获取成员变量对象

getDeclaredFields()获取全部
getDeclaredField()获取单个
在这里插入图片描述

	/*
		 * 利用反射技术获取成员变量
		 */
    	Class b = Book.class;
    	
    	Field [] fs = b.getDeclaredFields();
		for (Field f : fs) {
			System.out.println(f);
		}

2.5 反射获取方法对象

getDeclaredMethods()获取全部
getDeclaredMethod()获取单个

反射,以前是对象调方法,反射之后是方法调对象,new Dog d = new Dog(); —> d.eat()—> method01.invoke(d);

/*
		 * 利用反射技术获取 所有 成员方法
		 */
    	Class<?>  b = Book.class;
    	Method[] method1 =  b.getDeclaredMethods();
//    	method1.setAccessible(true);
    	for (Method method : method1) {
			System.out.println("返回方法名称:"+method.getName()+"返回方法参数类型:"+method.getReturnType()+"返回方法参数个数:"+method.getParameterCount());
		}
		/*
		 * 利用反射技术获取 单个 成员方法
		 */
		Class<?> b = Book.class;
		Method method1 = b.getDeclaredMethod("setTitle");
		Method method2 = b.getDeclaredMethod("setTitle", String.class);
//
//		System.out.println("返回方法名称:" + method1.getName() + "返回方法参数类型:" + method1.getReturnType() + "返回方法参数个数:"
//				+ method1.getParameterCount());
//		System.out.println("返回方法名称:" + method2.getName() + "返回方法参数类型:" + method2.getReturnType() + "返回方法参数个数:"
//				+ method2.getParameterCount());
		//暴力开权限
		method1.setAccessible(true);
		method2.setAccessible(true);
		//注意方法如果没有结果,返回null
		Book book =new Book();
		Object result1 = method1.invoke(book);
		Object result2 = method2.invoke(book,"Java进阶");

2.6 反射作用

1.可以再运行时得到一个累的全部成分然后操作
2.破坏封装性。
3.可以破坏泛型的约束性。(ArrayList< Integer>)
4.最重要的用途:做Java高级框架。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值