1. 基本介绍 715

1. Class也是类,因此也继承Object类 [类图]
2. Class类对象不是new出来的,而是系统创建的
3.对于某个类的Class类对象,在内存中只有一份, 因为类只加载一次
4.每个类的实例都会记得自己是由哪个Class实例所生成
5.通过Class对象可以完整地得到一个类的完整结构,通过一系列API
6. Class对象是存放在堆的
7.类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据(包括 方法代码,变量名,方法名,访问权限等等)
代码在com.stulzl.class_.包中
Class_01
package com.stulzl.class_;
import com.stulzl.cat.Cat;
//对Class类特点的梳理   715
public class Class_01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1. Class也是类,因此也继承Object类
        //2. Class类对象不是new出来的,而是系统创建的
        //(1) 传统 new 对象,调用ClassLoader 类的loadClass方法加载Cat类的Class对象
        /* ClassLoader 类
            public Class loadClass(String name) throws ClassNotFoundException {
                return loadClass(name, false);
            }
        */
        //Cat cat = new Cat();
        //反射方式
        /*
            ClassLoader 类, 仍然是通过 ClassLoader 类加载 Cat 类的 Class 对象
            public Class loadClass(String name) throws ClassNotFoundException {
                return loadClass(name, false);
            }
         */
        Class cls1 = Class.forName("com.stulzl.cat.Cat");
        //3.对于某个类的Class类对象,在内存中只有一份, 因为类只加载一次[演示]
        Class cls2 = Class.forName("com.stulzl.cat.Cat");
        //如果cls1和cls2d的hashCode值一样,说明二者是同一个对象
        System.out.println(cls1.hashCode());//356573597
        System.out.println(cls2.hashCode());//356573597
        //4.每个类的实例都会记得自己是由哪个Class实例所生成
        //5.通过Class对象可以完整地得到一个类的完整结构,通过一系列API
        //6. Class对象是存放在堆的
        //7.类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据
        // (包括 方法代码,变量名,方法名,访问权限等等)
    }
}Cat类
package com.stulzl.cat;
//反射的问题引入  710
//Cat类
public class Cat {
    private String name = "招财猫";
    public int age = 10;
    //无参构造器
    public Cat(){
    }
    //有参构造器
    public Cat(String name){
        this.name = name;
    }
    public void hi(){//常用方法
        //System.out.println("hi "+name);
    }
    public void cry(){
        System.out.println("喵喵喵叫……");
    }
}2. Class 类的常用方法 716

2.1 应用实例
代码在com.stulzl.class_02.
Class_02
package com.stulzl.class_02;
import com.stulzl.Car;
import java.lang.reflect.Field;
//Class 类的常用方法  716
public class Class_02 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        String classAllPath = "com.stulzl.Car";
        //获取到Car对应的Class对象
        //表示不确定的java类型,写不写都行
        Class cls = Class.forName(classAllPath);
        //输出cls
        System.out.println(cls);//显示cls对象是哪个类的Class类对象 即com.stulzl.Car
        System.out.println(cls.getClass());//输出cls运行类型,java.lang.Class
        //得到包名
        System.out.println(cls.getPackage().getName());//com.stulzl
        //得到全类名
        System.out.println(cls.getName());//com.stulzl.Car
        //通过cls创建对象实例
        //Object o = cls.newInstance();
        //可以强制类型转换即
        Car car = (Car)cls.newInstance();
        System.out.println(car);//Car{brand='宝马', price=500000, color='白色'}
        //通过反射获取对象的属性例如brand
        Field brand = cls.getField("brand");
        System.out.println(brand.get(car));//宝马//提示如果是私有属性会报错,后面在解决
        //通过反射给属性赋值
        brand.set(car,"奔驰");//通过反射给car对象的brand属性赋值为奔驰
        System.out.println(brand.get(car));//奔驰
        //希望可以得到所有的属性(字段)
        System.out.println("=====所有的字段属性=====");
        Field[] fields = cls.getFields();
        //使用增强for
        for(Field f:fields){
            System.out.println(f.getName());//获取名称
            System.out.println(f.get(car));//获取值
        }
        //使用普通for
        System.out.println("=====普通for========");
        for (int i = 0; i < 3; i++) {
            System.out.println(fields[i].getName());
            System.out.println(fields[i].get(car));
        }
    }
}Car类
package com.stulzl;
//Class 类的常用方法  716
//Car类
public class Car {
    public String brand = "宝马";
    public int price = 500000;
    public String color = "白色";
    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                ", color='" + color + '\'' +
                '}';
    }
}3. 获取 Class 类对象 717
1. 前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException, 实例: Class cls1 = Class.forName( "java.lang.Cat" );
应用场景:多用于配置文件,读取类全路径,加载类.
2. 前提:若已知具体的类,通过类的class获取,该方式最为安全可靠,程序性能
最高实例: Class cls2 = Cat.class;
应用场景:多用于参数传递,比如通过反射得到对应构造器对象.
3. 前提:已知某个类的实例,调用该实例的getClass() 方法获取Class对象,
实例: Class clazz =对象.getClass();//运行类型
应用场景:通过创建好的对象,获取Class对象.
4. 其他方式
ClassLoader cl =对象.getClass().getClassLoader(0;
Class clazz4 = cl.loadClass(“类的全类名”);
5. 基本数据(int, char,boolean,float,double,byte,long,short)按如下方式得到Class类对象

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

代码在com.stulzl.get_class.
GetClass_
package com.stulzl.get_class;
import com.stulzl.Car;
//演示得到class对象的各种方式  717
public class GetClass_ {
    public static void main(String[] args) throws ClassNotFoundException {
        //方式一  Class.forName()
        //1. 前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,
        // 可能抛出ClassNotFoundException,
        //应用场景:多用于配置文件,读取类全路径,加载类.
        String classAllPath  = "com.stulzl.Car";//这个全类名一般是通过配置文件得到的
        Class cls1 = Class.forName(classAllPath);
        System.out.println(cls1);
        //方式二  类名.class
        //2. 前提:若已知具体的类,通过类的class获取,该方式最为安全可靠,程序性能
        //应用场景:多用于参数传递,比如通过反射得到对应构造器对象.
        Class cls2 = Car.class;
        System.out.println(cls2);
        //方式三  对象.getClass()
        //3. 前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象,
        //应用场景:通过创建好的对象,获取Class对象.
        Car car = new Car();
        Class cls3 = car.getClass();//运行类型
        System.out.println(cls3);
        //方式四  通过类加载器来获取到类的Class对象
        //(1).先得到类加载器car
        ClassLoader classLoader = car.getClass().getClassLoader();
        //(2).通过类加载器的Class对象
        Class cls4 = classLoader.loadClass(classAllPath);
        System.out.println(cls4);
        //cls1 , cls2 , cls3 , cls4 其实是同一个对象
        System.out.println(cls1.hashCode());
        System.out.println(cls2.hashCode());
        System.out.println(cls3.hashCode());
        System.out.println(cls4.hashCode());
        //5. 基本数据(int, char,boolean,float,double,byte,long,short)
        // 按如下方式得到 Class 类对象
        Class integerClass = int.class;
        Class characterClass = char.class;
        Class booleanClass = boolean.class;
        System.out.println(integerClass);//int
        //6. 基本数据类型对应的包装类,可以通过 .TYPE 得到 Class 类对象
        //其它包装类 BOOLEAN, DOUBLE, LONG,BYTE 等等就不演示了
        Class type1 = Integer.TYPE;
        Class type2 = Character.TYPE;
        System.out.println(type1);//int
        System.out.println(integerClass.hashCode());//1735600054
        System.out.println(type1.hashCode());//1735600054
    }
}Car类
package com.stulzl;
//Class 类的常用方法  716
//Car类
public class Car {
    public String brand = "宝马";
    public int price = 500000;
    public String color = "白色";
    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                ", color='" + color + '\'' +
                '}';
    }
}4. 哪些类型有 Class 对象 718
4.1 如下类型有 Class 对象
外部类,成员内部类,静态内部类,局部内部类,匿名内部类
2. interface :接口
3.数组
4. enum :枚举
5. annotation :注解
6.基本数据类型
7.void
4.2 应用实例
代码在com.stulzl.all_type_class.
AllTypeClass
package com.stulzl.all_type_class;
import java.io.Serializable;
//演示哪些类型有 Class 对象  718
public class AllTypeClass {
    public static void main(String[] args) {
        //外部类
        Class cls1 = String.class;
        //接口
        Class cls2 = Serializable.class;
        //数组
        Class<Integer[]> cls3 = Integer[].class;
        //二维数组
        Class<float[][]> cls4 = float[][].class;
        //注解
        Class cls5 = Deprecated.class;
        //枚举
        Class cls6 = Thread.State.class;//State就是一个枚举
        //基本数据类型,例如long
        Class cls7 = long.class;
        //void数据类型
        Class cls8 = void.class;
        //Class
        Class cls9 = Class.class;//Class也是一种类
        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);
        System.out.println(cls9);
    }
}








