基础加强--类加载器&反射

类加载器--初步了解

类加载器--类加载时机

类加载的过程



字节码文件对象中存储类中的成员信息

类的加载过程-链接

  • 验证
  • 准备
  • 解析


类加载过程--初始化和小结

  • 总结

    案例说明加载过程

  • 验证安全隐患


类加载器的分类

类加载器--双亲委派模型

package com.loader;
//测试类加载器的使用
public class LoaderTest {
    public static void main(String[] args) {
    //获取系统类加载器
        final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        //获取系统类加载器的父加载器-----平台类加载器
        final ClassLoader parentClassLoader = systemClassLoader.getParent();
        //获取平台类加载器的父加载器-=--启动类加载器
        final ClassLoader loader = parentClassLoader.getParent();
        System.out.println("系统类加载器"+systemClassLoader);
        System.out.println("父类加载器"+parentClassLoader);
        System.out.println("启动类加载器"+loader);
    }
}

类加载器--常用方法

需要注意的是:需要加载的文件要写在src文件夹下面

package com.loader;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class LoaderTest1 {
    public static void main(String[] args) throws IOException {
        /*
        static ClassLoader getSystemClassLoader();获取系统类加载器
        InputStream getResourceAsStream(String name);加载某一个资源文件
         */
        //1.获取系统类加载器
        final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        //2.利用类加载器去加载一个指定的文件
        final InputStream is = systemClassLoader.getResourceAsStream("prop.properties");
        Properties properties = new Properties();
        properties.load(is);
        System.out.println(properties);
        is.close();

    }
}

反射

反射--概括



在过去的方式创建对象并调用方法的这种方式是死的,当改变了要调用的方法,大部分代码要重写。而反射创建对象并调用方法则更灵活

  • 总结

获取calss对象


关于字节码文件对象见上面的类加载器的内容*

  • 获取字节码文件对象的方式
package com.reflect;
//反射的三种创建对象的方式
public class ReflectDemo1 {
   public static void main(String[] args) throws ClassNotFoundException {
       //1.仅仅编译还没有被加载(源代码阶段)
       final Class<?> clazz = Class.forName("com.reflect.Student");
       System.out.println(clazz);//class com.reflect.Student
       //2.该类被加载,创建了字节码文件的对象
       final Class<Student> clazz1 = Student.class;
       System.out.println(clazz1);//class com.reflect.Student
       //3.该类的对象被创建
       final Student student = new Student();
       System.out.println(student.getClass());//class com.reflect.Student
   }
}
  • 总结

获取Constructor对象



  • 演示见以前的
    注意:被private修饰的构造方法不能直接使用(如果用反射直接使用将会报错),如果用反射强行使用需要临时取消访问检查

  • 举例:临时取消访问检查

package com.reflect;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

   private Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }


}
package com.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//使用反射创建对象()
public class ConstructorTest1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        method1();
    }

    private static void method1() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        //1.获取字节码文件对象
        final Class<?> clazz = Class.forName("com.reflect.Student");
        //2.获取构造方法的对象

        final Constructor<?> con = clazz.getDeclaredConstructor(String.class, int.class);
        con.setAccessible(true);//临时取消该构造方法的权限检查
        //3.利用构造方法创建对象
        final Student s1 = (Student) con.newInstance("张三", 17);
        System.out.println(s1);

    }
}
  • 如果不取消将会:

反射-小结

反射获取Field对象


利用Filed赋值和获取值

  • 为什么这2个方法都需要传递对象


  • get方法的使用

获取Method对象

利用Method对象运行方法

posted @ 2023-07-29 21:13  一往而深,  阅读(5)  评论(0编辑  收藏  举报