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虚拟机中去
代码:public class ClassLoaderDemo {
public static void main(String[] args) throws ClassNotFoundException {
//获取类加载器
ClassLoader classLoader=ClassLoaderDemo.class.getClassLoader();
System.out.println(classLoader);

//常用三种方式加载类
//使用ClassLoader.loadClas()来加载类,不会执行初始化块
System.out.println("---ClassLoader.loadClass()---");
classLoader.loadClass("com.gx.reflect.Test1");
//使用Class.forName(className)来加载类,默认会执行初始化块
System.out.println("---Class.forName(className)---");
Class.forName("com.gx.reflect.Test2");
//使用Class.forName(className,initialize,ClassLoader)来加载类,并指定ClassLoader,初始化时不执行静态代码块
//参数:类名,是否初始化,类加载器
System.out.println("Class.forName(className,initialize,ClassLoader) ");
Class.forName("com.gx.reflect.Test3",true,classLoader);
}
}
class Test1{
static {
System.out.println("Test1 静态初始化块");
}
}
class Test2{
static {
System.out.println("Test2 静态初始化块");
}
}
class Test3{
static {
System.out.println("Test3 静态初始化块");
}
}
Java反射机制:在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够 调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的 功能就称为java语言的反射机制。通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何 东西都可以。
代码:public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
//加载类获取类类型
Class<?>studentClass=Class.forName("com.gx.reflect.Student2");
//获取所有的构造器
System.out.println("---所有的构造器---");
Constructor[] constructors= studentClass.getDeclaredConstructors();
for (Constructor constructor : constructors) {
StringBuilder builder=new StringBuilder();
//修饰符
builder.append("\t"+Modifier.toString(constructor.getModifiers()));
//构造器名称
builder.append(" "+constructor.getName()+"(");
//构造器参数类型列表
Class<?>[] rarameterTypes=constructor.getParameterTypes();
for (Class<?> rarameterType : rarameterTypes) {
builder.append(rarameterType.getSimpleName()+",");
}
builder.append(")");
String str=builder.toString();
str=str.replace(",)", ")");
System.out.println(str);
}

System.out.println();
System.out.println("----所有的方法-----");
Method[] allmethods=studentClass.getDeclaredMethods();
for (int i = 0; i < allmethods.length; i++) {
StringBuffer sBuffer=new StringBuffer();
sBuffer.append("\t");
sBuffer.append(i+1);
sBuffer.append(":");
//获取修饰符
sBuffer.append(Modifier.toString(allmethods[i].getModifiers()));
sBuffer.append(" ");
//获取返回值类型
sBuffer.append(allmethods[i].getReturnType().getSimpleName());
sBuffer.append(" ");
//方法名称
sBuffer.append(allmethods[i].getName());
sBuffer.append("(");
//方法参数类型
Class<?>[] ptypes=allmethods[i].getParameterTypes();
for (int j = 0; j < ptypes.length; j++) {
sBuffer.append(ptypes[j].getSimpleName());
sBuffer.append(" ");
}
sBuffer.append(" )");
System.out.println(sBuffer.toString());
}

System.out.println();
System.out.println("---所有的成员变量----");
Field[] fields=studentClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
StringBuffer sBuffer=new StringBuffer();
sBuffer.append("\t");
sBuffer.append(i+1);
sBuffer.append(":");
//修饰符
sBuffer.append(Modifier.toString(fields[i].getModifiers()));
sBuffer.append(" ");
//类型
sBuffer.append(fields[i].getType().getSimpleName());
sBuffer.append(" ");
//成员变量名
sBuffer.append(fields[i].getName());
System.out.println(sBuffer.toString());
}

//-----通过反射实例化对象
System.out.println();
System.out.println("----通过反射实例化对象----");
Constructor constructor1=studentClass.getConstructor(String.class,int.class);
Student2 student1=(Student2) constructor1.newInstance("小寒",22);
System.out.println(student1);

Constructor constructor2=studentClass.getDeclaredConstructor();
//设置允许访问私有构造器
//私有的要设置允许访问,共有的直接访问
constructor2.setAccessible(true);
Student2 student2=(Student2) constructor2.newInstance();
System.out.println(student2);

//-----通过反射调用方法
System.out.println();
System.out.println("----通过反射调用方法----");
Method method1=studentClass.getMethod("getName");
String name= (String) method1.invoke(student1);//执行方法
System.out.println(name);

Method method2=studentClass.getDeclaredMethod("test2",String.class);
method2.setAccessible(true);
String str= (String) method2.invoke(student1, "这是参数");
System.out.println(str);

//----通过反射调用属性
System.out.println();
System.out.println("----通过反射调用属性----");
Field field1=studentClass.getDeclaredField("name");
field1.setAccessible(true);
String strName= (String) field1.get(student1);
System.out.println("strName="+strName);
field1.set(student1, "小红");//修改条件
System.out.println(student1);

}

}
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值