116.Class类
Class类分析
基本介绍:
-
Class也是类,因此也继承Object
-
Class类对象不是new出来的,而是系统创建的
public class Class01 {public static void main(String[] args) throws ClassNotFoundException {//Class类对象不是new出来的,而是系统创建的//(1)传统new对象Cat cat = new Cat();//(2) 反射方式,刚才没有debug到 ClassLoader类的 loadClass,原因是没有注销Cat cat = new Cat();// 仍然是通过 ClassLoader类加载Cat类的 Class对象Class aClass = Class.forName("reflection.question.Cat")} }
-
对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
-
每个类的实例都会记得自己是由哪个Class实例所生成
-
通过Class可以完整地得到一个类的完整结构,通过一些列API
-
Class对象是存放在堆的
-
类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据(包括 方法代码,变量名,方法名,访问权限等)
Class常用方法
public class Class01 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {String classAllPath = "reflection.question.Car";//1.获取到 Car 类 对应的 Class对象//<?> 表示不确定的Java类型Class<?> cls = Class.forName(classAllPath);//2.输出clsSystem.out.println(cls);//显示cls对象,是哪个类的Class对象 reflection.question.CarSystem.out.println(cls.getClass());//输出cls的运行类型 java.lang.Class//3.得到包名System.out.println(cls.getPackage().getName());//4.得到全类名System.out.println(cls.getName());//5.通过cls创建对象实例Car car = (Car)cls.newInstance();System.out.println(car);//car.toString()//6.通过反射获取属性 brandField brand = cls.getField("brand");System.out.println(brand.get(car));//宝马//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对象的六种方法
1.前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,肯能抛出ClassNotFoundException 实例:Class.forName("java.lang.Cat")
应用场景:多用于配置文件,读取类全路径,加载类
2.前提:若已知具体的类,通过类的class获取,该方式最为安全可靠,程序性能最高;
实例:Class cls2 = Cat.class
应用场景:多用于参数传递,比如通过反射得到对应构造器对象
3.前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象
实例:Class clazz = 对象.getClass();//运行类型
应用场景:通过创建好的对象,获取Class对象
4.其他方式
ClassLoader cl = 对象.getClass().getClassLoader();
Class clazz4 = cl.loadClass("类的全类名")
5.基本数据按如下方式得到对象
Class cls = 基本数据类型.class
6.基本数据类型对应的包装类,可以通过.TYPE得到Class类对象
Class cls = 包装类.TYPE
public class Class01 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {//1.Class.forNameString classAllPath = "reflection.question.Car";//通过读取配置文件获取Class<?> cls1 = Class.forName(classAllPath);System.out.println(cls1); //2. 类名.Class ,应用场景:多用于参数传递Class cls2 = Car.class;System.out.println(Car.class); //3. 对象.getClass() ,应用场景:有对象实例Car car = new Car();Class cls3 = car.getClass();System.out.println(cls3); //4.通过类加载器[4种]来获取到类的Class对象//(1)先得到类加载器 carClassLoader 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.基本数据Class<Integer> integerClass = int.class;Class<Character> characterClass = char.class;Class<Boolean> booleanClass = boolean.class;System.out.println(integerClass);//int //6.基本数据类型对应的包装类Class<Integer> type1 = Integer.TYPE;Class<Character> type2 = Character.TYPE;System.out.println(type1); System.out.println(integerClass.hashCode());System.out.println(type1.hashCode());//两个相同} }
哪些类型有Class对象
-
外部类,成员内部类,静态内部类,局部内部类,匿名内部类
-
interface:接口
-
数组
-
enum:枚举
-
annoation:注解
-
基本数据类型
-
void
public class Class01 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {Class<String> cls1 = String.class;//外部类Class<Serializable> cls2 = Serializable.class;//接口Class<Integer[]> cls3 = Integer[].class;//数组Class<float[][]> aClass = float[][].class;//二维数组Class<Deprecated> cls5 = Deprecated.class;//注解//枚举Class<Thread.State> cls6 = Thread.State.class;Class<Long> cls7 = long.class;//基本数据类型Class<Void> cls8 = void.class;//void数据类型Class<Class> cls9 = Class.class;}