Java反射02
2.Class类
2.1基本介绍
-
Class类也是类,因此也继承Object类
-
Class类对象不是new出来的,而是系统创建的
-
对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
-
每个类的实例都会记得自己是由哪个Class实例所生成
-
通过Class对象可以得到一个类的完整结构(通过一系列API)
-
Class对象是存放在堆的
-
类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据(包括 方法代码,变量名,方法名,访问权限等)
当我们加载完类之后,除了会在堆里生成一个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());//1554874502
System.out.println(cls2.hashCode());//1554874502
}
}
Class类对象不是new出来的,而是系统创建的:
- 在
Cat cat = new Cat();
处打上断点,点击force step into,可以看到
- 注释
Cat cat = new Cat();
,在Class cls1 = Class.forName("li.reflection.Cat");
处打上断点,可以看到 仍然是通过 ClassLoader类加载 Cat类的 Class对象
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() //返回表示数组类型的Class
public boolean isArray() //判断此class是否是一个数组
应用实例
Car:
package li.reflection;
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 + '\'' +
'}';
}
}
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.输出cls
System.out.println(cls);//将会显示cls对象是哪个类的Class对象 class li.reflection.Car
System.out.println(cls.getClass());//输出cls的运行类型 class java.lang.Class
//3.得到包名
System.out.println(cls.getPackage().getName());//li.