Java类加载机制和反射机制

Java类加载机制
jvm把class文件加载到内存,并对数据进行校验、解析和初始化,终形成jvm可以直 接使用的java类型的过程。
1、加载:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中 的运行时数据结构,在堆中生成一个代表这个类的java.lang.Class对象,作为方 法区类数据的访问入口。
2、链接:将java类的二进制代码合并到jvm的运行状态之中的过程,链接过程又分为3 个过程:
(1)验证:确保加载的类信息符合jvm规范,没有安全方面的问题。
(2)准备:正式为类变量(static变量)分配内存并设置类变量初始值的阶段, 这些内存都将在方法区中进行分配。
(3)解析:虚拟机常量池内的符号引用替换为直接引用的过程。(比如String s =“aaa”,转化为 s的地址指向“aaa”的地址)
3、初始化:初始化阶段是执行类构造器方法的过程。类构造器方法是由编译器自动收 集类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的。
(1)当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先初始化其父类的初始化
(2)虚拟机会保证一个类的构造器方法在多线程环境中被正确加锁和同步
(3)当访问一个java类的静态域时,只有真正声明这个静态变量的类才会被初始化。
ClassLoader类加载器
ClassLoader类加载器的作用就是将 .class 文件加载到JVM虚拟机中去
类加载器简单使用示例代码:

/**  * ClassLoader 类加载器  *
1 2 3
 * @author sxj  *  */ 
public class Demo1 {
	public static void main(String[] args) throws ClassNotFoundException{
		//获取类加载器 
		ClassLoader classLoader = Demo1.class.getClassLoader();
		//常用三种方式加载类 
		// 使用ClassLoader.loadClass()来加载类,不会执行初始化块 
		System.out.println("‐‐ClassLoader.loadClass()‐‐");
		classLoader.loadClass("com.gx.Demo.Test1");
		
		// 使用Class.forName(clssName)来加载类,默认会执行初始化块 
		System.out.println("‐‐Class.forName(clssName)‐‐");
		Class.forName("com.gx.Demo.Tes2");
		
		// 使用Class.forName(className,initialize,ClassLoader)来加载类,并指定ClassLo 
		// 参数:类名,是否初始化,类加载器 
		System.out.println("‐‐Class.forName(className,initialize,ClassLoader)‐‐");
		Class.forName("com.gx.Demo.Tes3",false,classLoader); 
	}
}

class Test1{
	static{
		System.out.println("Test1 静态初始化块");
	}
}
class Tes2{
	static{
		System.out.println("Tes2 静态初始化块");
	}
}
class Tes3{
	static{
		System.out.println("Tes3 静态初始化块");
	}
}

示例代码执行结果:
在这里插入图片描述
Java反射机制
Java的反射机制是在运行状态中,对于任何一个类,都能够知道这个类的所有属性和方法;对于任何一个对象,都能调用它的任何一个方法。这种动态获取信息和动态调用对象的方法的功能称为Java语言的的反射机制。(主要是指程序可以访问,检测和修改它本身状态或行为的一种能力)简单来说,反射机制是指程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获取类的所有信息。包括其访问修饰符,父类,实现的接口,属性和方法的所有信息,并可在运行时创建对象,修改属性(包括私有的),调用方法(包括私有的)。
Class类常用类
在这里插入图片描述
示例代码:

public class Demo1 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException{
		//加载类 
		Class<?> class1=Demo1.class.getClassLoader().loadClass("com.gx.Demo.Person");
		Class<?> class2=Class.forName("com.gx.Demo.Person");
		Class<?> class3=Person.class;
		Class<?> class4=new Person("", 1).getClass();
		
		//==获取构造器 
		System.out.println("构造器有:");
		Constructor<?>[] constructors= class2.getDeclaredConstructors();
		for (Constructor<?> constructor : constructors) {
			StringBuilder builder=new StringBuilder();
			builder.append("\t" +Modifier.toString(constructor.getModifiers()));
			builder.append(" "+constructor.getName());
			builder.append("(");
			Class<?>[] rarameterTypes = constructor.getParameterTypes();
			for (Class<?> rarameterType : rarameterTypes) {
				builder.append(rarameterType.getSimpleName()+", ");
			}
			builder.append(")");
			System.out.println(builder.toString());
		}
		
		System.out.println("方法有:");
		Method[] methods= class2.getDeclaredMethods();
		for (Method method : methods) {
			StringBuilder builder=new StringBuilder();
			// 获取修饰符 
			builder.append("\t"+Modifier.toString(method.getModifiers()));
			Class<?> returnType=method.getReturnType();
			builder.append(" "+returnType.getSimpleName());
			builder.append(" "+method.getName());
			builder.append("(");
			Class<?>[] rarameterTypes = method.getParameterTypes();
			for (Class<?> rarameterType : rarameterTypes) {
				builder.append(rarameterType.getSimpleName()+", ");
			}
			builder.append(")");
			System.out.println(builder.toString());
		}
		
		
		//获取所有的属性 
		System.out.println("所有的属性:");
		Field[] fields=class2.getDeclaredFields();
		for (Field field : fields) {
			StringBuilder builder=new StringBuilder();
			builder.append("\t"+Modifier.toString(field.getModifiers()));
			builder.append(" "+field.getType().getSimpleName());
			builder.append(" "+field.getName());
			System.out.println(builder.toString());
		}
		
		
		System.out.println("‐‐‐‐‐‐‐‐‐‐‐通过反射机制调用构造器实例化一个类的对象‐‐‐‐‐‐‐");		
		Constructor<?> constructor1=class2.getConstructor(String.class,int.class);
		Person person=(Person) constructor1.newInstance("小明",20);
		System.out.println(person.getName()+" "+person.getAge());
		
		Constructor<?> constructor2=class2.getDeclaredConstructor();
		constructor2.setAccessible(true);
		Person person2=(Person) constructor2.newInstance();
		person2.setName("小米");
		person2.setAge(20);
		System.out.println(person2.getName()+" "+person2.getAge());
		
		
		System.out.println("-----------通过私有的构造器实例对象--------");
		//可以访问
		Method method = class2.getMethod("say", String.class);
		String str=  (String) method.invoke(person, "可以访问的方法");
		System.out.println(str);
		
		//调用无法直接访问的方法 
		System.out.println("-------------------调用无法直接访问的方法-------------");
		Method method2=class2.getDeclaredMethod("test");
		method2.setAccessible(true);
		method2.invoke(person);
		
		

		System.out.println("-----------通过反射机制获取或者设置成员变量---------");
		//设置值 
		Field field=class2.getDeclaredField("name");
		field.setAccessible(true);
		field.set(person, "小小明");
		System.out.println(person.say("111111"));
		///获取值 
		System.out.println(field.get(person));
	}
}

示例代码运行结果
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值