各自努力,最高处见!加油!
反射(二)Class类系统介绍
一、基本介绍
- Class也是类,因此也继承Object类。
- Class类对象不是new出来的,而是系统创建的。(系统会将类的信息加载到堆中)
- 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次。(可以通过查看类的hashCode来确定)
Class cls=Class.forName("com.xmtedu.Cat");//类路径 得到一个类的对象
System.out.println(cls.hashCode());
- 每个类的实例都会记得自己是由哪个Class 实例产生的
- 通过Class对象可以完整地得到一个类的完整结构,通过一系列API
- Class对象是存放在堆中
- 类的字节码二进制数据,是放在方法去的,有的地方称为类的元数据。
二、Class类对象的8个常用方法(见代码块)
import com.xmtedu.Car;
import java.lang.reflect.Field;
/**
* 演示Class类的常用方法
*/
public class Class02 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
String classAllPath="com.xmtedu.Car";
//1、获取到Car类对应的Class对象
//<?>表示不确定的Java类型
Class<?> cls = Class.forName(classAllPath);
//2、输出cls 两种输出的意义不一样
System.out.println(cls);//显示cls对象,显示是哪个类的Class对象 class com.xmtedu.Car
System.out.println(cls.getClass());//真正的运行对象 class java.lang.Class
//3、得到包名(该类所在的包名)
System.out.println(cls.getPackage().getName());//com.xmtedu
//4、得到一个全类名
System.out.println(cls.getName());//com.xmtedu.Car
//5、通过cls创建对象实例
Car car = (Car)cls.newInstance();
System.out.println(car);
//6、通过反射获的属性 brand
Field brand = cls.getField("brand");//获得了一个brand的属性,在调用的时候要传入一个Car的对象
System.out.println(brand.get(car));//BMW
//7、通过反射给属性赋值
brand.set(car,"大奔");
System.out.println(brand.get(car));//大奔
//8、得到所有属性
Field[] fields = cls.getFields();
for (Field f : fields) {
System.out.println(f.getName());
}
}
}
三、获取Class对象的六种方式
![在这里插入图片描述](https://img-blog.csdnimg.cn/5ea38bfb5bf6430d83f631d2bdbc82ad.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBATUjmoqblm54=,size_20,color_FFFFFF,t_70,g_se,x_16
Class对象里面装的是一个类,如一个Cat类。
1、Class.forName(“类全路径”);
前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundExecption
应用场景:多用于配置文件,读取类的全路径,加载类
2、类名.Class
前提:若已知具体的类,通过类的class获取,该方式最为可靠,程序性能最高。Class cls2=Cat.class;
应用场景:多用于参数传递,比如通过反射得到对应构造器对象。Constructor constructor=cls.getConstructor(String.class)
3、对象.getClass()
前提:若已知具体的类,通过类的class获取,该方式最为可靠,程序性能最高。Class cls2=Cat.class;
应用场景:多用于参数传递,比如通过反射得到对应构造器对象。Constructor constructor=cls.getConstructor(String.class)
4、通过类加载器得到Class对象
- 先获得一个类加载器
- 然后通过类加载器得到Class对象
5、基本数据类型[类型名.class]获取Class对象
6、基本数据类型对应的包装类,可以通过TYPE得到Class类对象
示例代码:
import com.xmtedu.Car;
public class getClass {
public static void main(String[] args) throws ClassNotFoundException {
String classAllPath="com.xmtedu.Car";
Class<?> cls = Class.forName(classAllPath);
System.out.println(cls);
Class<Car> cls2 = Car.class;
System.out.println(cls2);
Car car=new Car();
Class<? extends Car> cls3 = car.getClass();
System.out.println(cls3);
//4、通过类加载器(4)来获取到类的Class对象
//(1)先获得一个类加载器
ClassLoader classLoader = car.getClass().getClassLoader();
//(2)通过类加载器得到Class对象
Class<?> cls4 = classLoader.loadClass(classAllPath);
//5、基本数据类型(int char boolean float double byte long short)按如下方式得到Class类对象
Class<Integer> integerClass = int.class;
Class<Character> characterClass = char.class;
Class<Boolean> booleanClass = boolean.class;
System.out.println(integerClass);//int
//6、基本数据类型对应的包装类,可以通过TYPE得到Class类对象
Class<Integer> type1=Integer.TYPE;
Class<Character> type2 = Character.TYPE;
System.out.println(type1);
//验证integerClass和type1是否是一样的Class对象
System.out.println(integerClass.hashCode());
System.out.println(type1.hashCode());
}
}
四、哪些类有Class对象
- 外部类,成员内部类,静态内部类,局部内部类,匿名内部类
- interface:接口
- 数组
- enum:枚举
- annotation:注解
- 基本数据类型
- void