Java高级Day42-Class类
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.输出cls System.out.println(cls);//显示cls对象,是哪个类的Class对象 reflection.question.Car System.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.通过反射获取属性 brand Field 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.forName String 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)先得到类加载器 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.基本数据 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; }