day43-反射02

2.Class类2.1基本介绍

day43-反射02

文章插图
  1. Class类也是类,因此也继承Object类
    day43-反射02

    文章插图
  2. Class类对象不是new出来的,而是系统创建的
  3. 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
  4. 每个类的实例都会记得自己是由哪个Class实例所生成
  5. 通过Class对象可以得到一个类的完整结构(通过一系列API)
  6. Class对象是存放在堆的
  7. 类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据(包括 方法代码,变量名,方法名,访问权限等)
    当我们加载完类之后 , 除了会在堆里生成一个Class类对象,还会在方法区生成一个类的字节码二进制数据(元数据)
例子:
package li.reflection.class_;import li.reflection.Cat;//对Class类的特点的梳理public class Class01 {public static void main(String[] args) throws ClassNotFoundException {//1.Class类对象不是new出来的,而是系统创建的//1.1.传统的 new对象/**通过ClassLoader类中的loadClass方法:*public Class<?> loadClass(String name) throws ClassNotFoundException {*return loadClass(name, false);*}*///Cat cat = new Cat();//1.2反射的方式/**在这里debug,需要先将上面的Cat cat = new Cat();注释掉 , 因为同一个类只加载一次,否则看不到loadClass方法* (这里也验证了:3.对于某个类的Class类对象 , 在内存中只有一份,因为类只加载一次)* 仍然是通过 ClassLoader类的loadClass方法加载 Cat类的 Class对象*public Class<?> loadClass(String name) throws ClassNotFoundException {*return loadClass(name, false);*}*/Class cls1 = Class.forName("li.reflection.Cat");//2.对于某个类的Class类对象,在内存中只有一份 , 因为类只加载一次Class cls2 = Class.forName("li.reflection.Cat");//这里输出的hashCode是相同的,说明cls1和cls2是同一个Class类对象System.out.println(cls1.hashCode());//1554874502System.out.println(cls2.hashCode());//1554874502}}【day43-反射02】Class类对象不是new出来的,而是系统创建的:
  1. Cat cat = new Cat();处打上断点,点击force step into , 可以看到

day43-反射02

文章插图
  1. 注释Cat cat = new Cat();,在Class cls1 = Class.forName("li.reflection.Cat");处打上断点,可以看到 仍然是通过 ClassLoader类加载 Cat类的 Class对象

day43-反射02

文章插图
2.2Class类常用方法public static Class<?> forName(String className)//传入完整的“包.类”名称实例化Class对象public Constructor[] getContructors() //得到一个类的全部的构造方法public Field[] getDeclaredFields()//得到本类中单独定义的全部属性public Field[] getFields()//得到本类继承而来的全部属性public Method[] getMethods()//得到一个类的全部方法public Method getMethod(String name,Class..parameterType)//返回一个Method对象,并设置一个方法中的所有参数类型public Class[] getInterfaces() //得到一个类中锁实现的全部接口public String getName() //得到一个类完整的“包.类”名称public Package getPackage() //得到一个类的包public Class getSuperclass() //得到一个类的父类public Object newInstance() //根据Class定义的类实例化对象public Class<?> getComponentType() //返回表示数组类型的Classpublic boolean isArray() //判断此class是否是一个数组
应用实例
Car:
package li.reflection;public class Car {public String brand = "宝马";public int price = 500000;public String color ="白色";@Overridepublic String toString() {return "Car{" +"brand='" + brand + '\'' +", price=" + price +", color='" + color + '\'' +'}';}}Class02:
package li.reflection.class_;import li.reflection.Car;import java.lang.reflect.Field;//演示Class类的常用方法public class Class02 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {String classAllPath = "li.reflection.Car";//1.获取到 Car类 对应的 Class对象//<?>表示不确定的Java类型Class<?> cls = Class.forName(classAllPath);//2.输出clsSystem.out.println(cls);//将会显示cls对象是哪个类的Class对象class li.reflection.CarSystem.out.println(cls.getClass());//输出cls的运行类型 class java.lang.Class//3.得到包名System.out.println(cls.getPackage().getName());//li.reflection :Class对象对应的类是在哪个包下面//4.得到全类的名称System.out.println(cls.getName());//li.reflection.Car//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());//依次输出各个属性字段的名称}}}

推荐阅读