Java反射——Class类——第二章

Java反射——反射机制问题——第一章
Java反射——Class类——第二章
Java反射——类加载——第三章
Java反射——反射获取类的结构信息——第四章

1:Class类基本介绍

  1. Class也是类,因此也继承Object类
    在这里插入图片描述

  2. Class类对象不是new出来的,而是系统创建的
    如下代码演示,可以在7,12行分别进行断点调试,可以追到ClassLoader加载器中的loadClass方法

    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }
        //2. Class类对象不是new出来的,而是系统创建的
        //(1)传统new对象
        //    public Class<?> loadClass(String name) throws ClassNotFoundException {
        //        return loadClass(name, false);
        //    }
7       People people = new People();
        //(2) 反射方式
        //    public Class<?> loadClass(String name) throws ClassNotFoundException {
        //        return loadClass(name, false);
        //    }
12        Class<?> cls = Class.forName("com.class_.Class01");
  1. 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
    在第二点中,我们如果没有注释掉第7行的代码,那么我们在第12行进行断点调试,就不会追到ClassLoader加载器中的loadClass方法,因为对于某个类的Class类对象,在内存中只有一份,因为类只加载一次。

  2. 每个类的实例都会记得自己是由哪个Class实例所生成

  3. 通过Class对象可以完整地得到一个类的完整结构,通过一系列API
    在这里插入图片描述

  4. Class对象是存放在堆的

  5. 类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据(包括方法代码,变量名, 方法名,访问权限等等)
    当我们类加载完成以后,除了会在堆生成class类对象,在方法区还会生成class类的字节码二进制数据,方法区会引用到class类对象
    在这里插入图片描述

2:Class常用方法演示

代码演示

public class Class02 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        String name="com.reflection.People";
        //<?> 表示不确定的Java类型
        //1:获取到People类,对应的Class对象
        Class<?> cls = Class.forName(name);
        //2:输出cls
        System.out.println(cls);//class com.reflection.People  显示class对象,是哪个类的class对象
        System.out.println(cls.getClass());//class java.lang.Class  输出cls运行实例
        //3:通过cls创建对象实例
        Object o = cls.newInstance();
        System.out.println(o);
        Field name1 = cls.getField("name");
        System.out.println(name1.get(o));
        name1.set(o,"zlj");
        System.out.println(name1.get(o));
        //4:得到类的名字
        System.out.println(cls.getName());
        //5:获取类加载器
        System.out.println(cls.getClassLoader());
        //6:获取所有的属性(字段),同理也可以获取所有的构造器和方法
        Field[] fields = cls.getFields();
       for (Field f:fields){
           System.out.println(f.getName());
       }
//        Constructor<?>[] constructors = cls.getConstructors();
//       for (Constructor constructor:constructors){
//           System.out.println(constructor.getName());
//       }
//        Method[] methods = cls.getMethods();
//       for (Method method:methods){
//           System.out.println(method.getName());
//       }
    }
}

People .java

public class People {
    public String name="zlj";
    public String age="zlj";
    public String sum="zlj";
    public People(){
        this.name="zzg";
    }
    public People(String name){
        this.name=name;
    }
    public void hi(){
     //   System.out.println("hi"+name);
    }
    public void cry(){
        System.out.println("cry"+name);
    }
}

演示

class com.reflection.People
class java.lang.Class
com.reflection.People@677327b6
zzg
zlj
com.reflection.People
sun.misc.Launcher$AppClassLoader@18b4aac2
name
age

3:获取Class对象的6种方式

在程序运行的不同阶段,我们可以使用不同的方法来获取Class对象
如下图,在代码/编译阶段,我们可以使用Class.forName();在Class加载阶段,我们可以使用类.class;在Runtime运行阶段,我们可以使用对象.getClass();在反射的时候,我们可以通过类加载器得到class对象
在这里插入图片描述

  1. 前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException,

实例: Class cls1 =Class.forName( “java.lang.People” );

应用场景:多用于配置文件,读取类全路径,加载类.

  1. 前提:若已知具体的类,通过类的class获取,该方式最为安全可靠,程序性能最高

实例: Class cls2 = Cat.class;

应用场景:多用于参数传递,比如通过反射得到对应构造器对象.

  1. 前提:已知某个类的实例,调用该实例的getClass(方法获取Class对象,

实例:Class clazz =对象.getClass();//运行类型

应用场景:通过创建好的对象,获取Class对象.

  1. 通过类加载获取class对象

实例:
ClassLoader cl =对象.getClass().getClassLoader();
Class clazz4 = cl.loadClass( "类的全类名”);

  1. 基本数据(int, char, boolean,float,double,byte,long,short)按如下方式得到Class类对象

实例:Class cls =基本数据类型.class

  1. 基本数据类型对应的包装类,可以通过.TYPE得到Class类对象

实例:Class cls =包装类.TYPE

如下对上面的六种方法进行代码演示

public class GetClass_6 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1:前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
        Class<?> cls1 = Class.forName("com.reflection.People");
        System.out.println(cls1);
        //2.前提:若已知具体的类,通过类的class获取,该方式最为安全可靠,程序性能最高实例:
        Class cls2= People.class;
        System.out.println(cls2);
        //3.前提:已知某个类的实例,调用该实例的getClass(方法获取Class对象,
        People people = new People();
        Class<? extends People> cls3 = people.getClass();
        System.out.println(cls3);
        //4.前提:通过类加载获取class对象
        //1).先得到类加载器people
        ClassLoader classLoader = people.getClass().getClassLoader();
        //2).通过类加载器得到class对象
        Class<?> cls4 = classLoader.loadClass("com.reflection.People");
        System.out.println(cls4);
        //cls1 cls2 cls3 cls4是同一个对象
        //5.基本数据(int, char, boolean,float,double,byte,long,short)按如下方式得到Class类对象
        System.out.println(int.class);
        System.out.println(char.class);
        //6. 基本数据类型对应的包装类,可以通过.TYPE得到Class类对象
        System.out.println(Integer.TYPE);
        System.out.println(Character.TYPE);
    }
}

4:那些类型有Class对象

我们来梳理一下,在Java中那些类有Class对象
如下类型有Class对象

  1. 外部类,成员内部类,静态内部类,局部内部类,匿名内部类

  2. interface :接口

  3. 数组

  4. enum: 枚举

  5. annotation :注解

  6. 基本数据类型

  7. void

AllTypeClass .java

public class AllTypeClass {
    public static void main(String[] args) {
        Class<String> cls1 = String.class;//外部类
        Class<Serializable> cls2 = Serializable.class;//接口类
        Class<float[][]> cls3 = float[][].class;//二维数组
        Class<int[]> cls4 = int[].class;//一维数组
        Class<Deprecated> cls5 = Deprecated.class;//注解
        Class<Thread.State> cls6 = Thread.State.class;//枚举
        Class<String> cls7 = String.class;//基本数据类型
        Class<Void> cls8 = void.class;;//void
        System.out.println(cls1);
        System.out.println(cls2);
        System.out.println(cls3);
        System.out.println(cls4);
        System.out.println(cls5);
        System.out.println(cls6);
        System.out.println(cls7);
        System.out.println(cls8);
    }
}
class java.lang.String
interface java.io.Serializable
class [[F
class [I
interface java.lang.Deprecated
class java.lang.Thread$State
class java.lang.String
void
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值