类加载与Class类

1.类加载器:

      概述:是负责将磁盘上的某个class文件读取到内存并生成Class对象
      如何获取类加载器:
          类的字节码对象.getClassLoader()

2.Java中有三种类加载器,它们分别用于加载不同种类的class

      - 启动类加载器:用于加载系统类库 <java_home>\bin目录下的class,比如  .jar
      - 扩展类加载器:用于加载扩展类库 <java_home>\lib\ext目录下的class
      - 应用程序加载器:用于加载我们自定义类的加载器

// 获取 Test类的类加载器
ClassLoader c1 = Tests.class.getClassLoader();
System.out.println(c1);// jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
// 获取 Student类的类加载器
ClassLoader c2 = Student.class.getClassLoader();
System.out.println(c2);// jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
// 获取 String类的类加载器
ClassLoader c3 = String.class.getClassLoader();
System.out.println(c3);// null
/*
* API中说明:一些实现可能使用null来表示引导类加载器。
* 如果此类由引导类加载器加载,则此方法将在此类实现中返回null
* */
System.out.println("=====================委派机制============");
System.out.println(c1.getParent());// jdk.internal.loader.ClassLoaders$PlatformClassLoader@6e8dacdf
//System.out.println(c3.getParent());// java.lang.NullPointerException
System.out.println(c1.getParent().getParent());// null,最高层

3.Class对象的获取方式

IDEA 工具中的对象是怎么知道类有哪些属性和哪些方法的?
   - 通过反射技术对 对象进行了解剖,获取了类的所有成员属性和方法
反射的概念
    - 反射是一种机制,利用该机制可以在程序运行的过程中对类进行解剖 并操作类中的所有成员变量、方法以及构造
使用反射操作类成员的前提
      - 要获得该类字节码文件对象,就是Class对象
反射在实际开发中引用
      - IDEA工具,Eclipse工具等代码开发工具都是反射机制,能够知道类.之后该类中的所有成员
      - 后期要学习的各种框架
总结:
      通过反射技术去获取一个类的成员变量,方法,构造方法等,并可以访问
      因此,我们要了解反射机制,使用反射,就需要获取Class对象,这是使用反射操作的前提
获取Class的方式:
      1.通过类名.getClass
      2.通过对象名称.getClass()
      3.通过Class的静态方法获得:public static Class<?> forName(String className)
              注意:每一个类的Class对象都只有一个

public class Tests {

    public static void main(String[] args) throws ClassNotFoundException {
        // 通过类名称.class
        Class<Student> c1 = Student.class;

        //通过对象名称.getClass()
        Student s = new Student();
        Class<? extends Student> c2 = s.getClass();

        // 通过Class静态方法获得
        Class<?> c3 = Class.forName("com.donglan.demo07_Class对象的获取方式.Student");

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
    }
}





public class Student {
    public String name;

}

4.Class类的常用方法

      String getSimpleName():获得类的名字字符串:类名
      String getName():获得类全名:包名+类名
      T newInstance():创建Class对象关联类的对象

public class Tests {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException {


        // 获得Student类的Class对象
        Class<Student> c = Student.class;

        // 获得类名字符串
        String name = c.getSimpleName();
        System.out.println(name);// Student

        // 获得类全名
        String name1 = c.getName();
        System.out.println(name1);// com.donglan.demo07_Class对象的获取方式.Student

        // 创建Student对象
        Student student = c.newInstance();// 其实就相当于调用了Student类中的无参构造方法
        System.out.println(student);// 7a79be86

    }
}

5.反射之操作构造方法

Java中一切皆对象,该类中的每一个构造方法都属于一个对象,那么我们在定义Student s的时候,通过对向赋值的方式给S赋值
Student s = new Student();
其实我们把 public Student(){}无参构造方法看作一个对象
Student s = 对象1(public Student(){})

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

    public Student() {
    }

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

    public Student(String name) {
        this.name = name;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Constructor概述
      类中的每一个构造方法都是一个Constructor类的对象
反射之操作构造方法的目的
      获得Constructor对象来创建类的对象
使用:
      1.如何通过反射获取一个类的构造方法:Class类的方法
          - public Constructor<T> getConstructor(Class<?>... parameterTypes)
                      根据参数类型获得对应的Constructor对象
                      只能获得public修饰的构造方法
          - public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
                      根据参数类型获得对应的Constructor对象
                      可以是public、protected、默认、private修饰符修饰的构造方法
          - public Constructor<?>[] getConstructors()
                      获得类中的所有构造方法,只能获取public修饰的
          - public Constructor<?>[] getDeclaredConstructors()
                      获得类中所有的构造方法
                      可以是public、protected、默认、private修饰符修饰的构造方法
      2.如何通过反射执行获取的构造方法:Constructor的方法
          - public T newInstance(Object ... initargs)
                  根据指定的参数创建对象
          - public void setAccessible(boolean flag)
                  设置“暴力反射”   : 是否取消权限检查,true是取消权限检查,false是不取消

public class Tests {

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 获得Student的Class对象
        Class<Student> c = Student.class;
        // 获取单个构造方法
        // 获取无参构造方法
        Constructor<Student> constructor1 = c.getDeclaredConstructor();
        System.out.println(constructor1);
        // 获取满参构造方法
        Constructor<Student> constructor2 = c.getDeclaredConstructor(String.class,int.class);
        System.out.println(constructor2);
        // 获取单参的构造方法
        Constructor<Student> constructor3 = c.getDeclaredConstructor(String.class);
        System.out.println(constructor3);
        Constructor<Student> constructor4 = c.getDeclaredConstructor(int.class);
        System.out.println(constructor4);
        System.out.println("============================================");
        // 获取所有构造方法
        Constructor<?>[] constructors = c.getDeclaredConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }

        System.out.println("============================================");

        // 通过执行 constructor1 表示的构造方法来创建Student对象
        Student s1 = constructor1.newInstance();
        System.out.println(s1);
        // 通过执行 constructor2 表示的构造方法来创建Student对象
        Student s2 = constructor2.newInstance("张三",18);
        System.out.println(s2);
        // 通过执行 constructor3 表示的构造方法来创建Student对象

        // 取消constructor3表示的构造方法的权限检查
        constructor4.setAccessible(true);
        Student s4 = constructor4.newInstance(18);
        System.out.println(s4);


    }


}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值