Java Class类

Java中,无论生成某个类的多少个对象,这些对象都会对应于同一个Class对象,这个Class对象是由JVM生成的,通过它能够获悉整个类的结构。要想使用反射,首先需要获得待操作的类所对应的Class对象。

原理

所有的java类都是继承了object这个类,在object这个类中有一个方法:getclass().这个方法是用来取得该类已经被实例化了的对象的该类的引用,这个引用指向的是Class类的对象。我们自己无法生成一个Class对象(构造函数为private),而 这个Class类的对象是在当各类被调入时,由 Java 虚拟机自动创建 Class 对象,或通过类装载器中的 defineClass 方法生成。我们生成的对象都会有个字段记录该对象所属类在CLass类的对象的所在位置。如下图所示:

Java Class类原理

获取class对象方法

1.使用Class类的静态方法

eg:Class.forName(“java.lang.String”);

2.使用类的.class语法

eg:Class c = Employee.class;

3.使用对象的getClass()方法

eg:Employee e = new Employee();  Class c3 = e.getClass(); 

例子

public class ClassTest {
    public static void main(String [] args)throws Exception{
        String str1="abc";
        Class cls1=str1.getClass();
        Class cls2=String.class;
        Class cls3=Class.forName("java.lang.String");
        System.out.println(cls1==cls2);
        System.out.println(cls1==cls3);
    }
}

返回结果为:true,true.

方法

forName(String classname)

该方法返回给定串名相应的Class对象。

getClassLoader()

获取该类的类装载器。

getComponentType()

如果当前类表示一个数组,则返回表示该数组组件的Class对象,否则返回null。

getConstructor(Class[])

返回当前Class对象表示的类的指定的公有构造子对象。

getConstructors()

返回当前Class对象表示的类的所有公有构造子对象数组。

getDeclaredConstructor(Class[])

返回当前Class对象表示的类的指定已说明的一个构造子对象。

getDeclaredConstructors()

返回当前Class对象表示的类的所有已说明的构造子对象数组。

getDeclaredField(String)

返回当前Class对象表示的类或接口的指定已说明的一个域对象。

getDeclaredFields()

返回当前Class对象表示的类或接口的所有已说明的域对象数组。

getDeclaredMethod(String,Class[])

返回当前Class对象表示的类或接口的指定已说明的一个方法对象。

getDeclaredMethods()

返回Class对象表示的类或接口的所有已说明的方法数组。

getField(String)

返回当前Class对象表示的类或接口的指定的公有成员域对象。

getFields()

返回当前Class对象表示的类或接口的所有可访问的公有域对象数组。

getInterfaces()

返回当前对象表示的类或接口实现的接口。

getMethod(String,Class[])

返回当前Class对象表示的类或接口的指定的公有成员方法对象。

getMethods()

返回当前Class对象表示的类或接口的所有公有成员方法对象数组,包括已声明的和从父类继承的方法。

getModifiers()

返回该类或接口的Java语言修改器代码。

getName()

返回Class对象表示的类型(类、接口、数组或基类型)的完整路径名字符串。

getResource(String)

按指定名查找资源。

getResourceAsStream(String)

用给定名查找资源。

getSigners()

获取类标记。

getSuperclass()

如果此对象表示除Object外的任一类,那么返回此对象的父类对象。

isArray()

如果Class对象表示一个数组则返回true,否则返回false。

isAssignableFrom(Class)

判定Class对象表示的类或接口是否同参数指定的Class表示的类或接口相同,或是其父类。

isInstance(Object)

此方法是Java语言instanceof操作的动态等价方法。

isInterface()

判定指定的Class对象是否表示一个接口类型。

isPrimitive()

判定指定的Class对象是否表示一个Java的基类型。

newInstance()

创建类的新实例。

toString()

将对象转换为字符串。

例子

class Person {
    public Person() {}
    public Person(String name) {
        this.name = name;
    }
    public Person(int age) {
        this.age = age;
    }
    public Person(String name, int age) {
        this.age = age;
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }@Override public String toString() {
        return "[" + this.name + "  " + this.age + "]";
    }
    private String name;
    private int age;
}

class classtest {
    public static void main(String[] args) {
        Class < ?>demo = null;
        try {
            demo = Class.forName("Reflect.Person");
        } catch(Exception e) {
            e.printStackTrace();
        }
        Person per1 = null;
        Person per2 = null;
        Person per3 = null;
        Person per4 = null;
        //取得全部的构造函数
        Constructor < ?>cons[] = demo.getConstructors();
        try {
            per1 = (Person) cons[0].newInstance();
            per2 = (Person) cons[1].newInstance("Rollen");
            per3 = (Person) cons[2].newInstance(20);
            per4 = (Person) cons[3].newInstance("Rollen", 20);
        } catch(Exception e) {
            e.printStackTrace();
        }
        System.out.println(per1);
        System.out.println(per2);
        System.out.println(per3);
        System.out.println(per4);
    }
}

执行结果:

[null  0]
[Rollen  0]
[null  20]
[Rollen  20]

总结

1. 在运行期间,如果我们要产生某个类的对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。如果没有被加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已被加载到内存,就可以用它来产生该类型的所有对象,虚拟机只会产生一份字节码, 用这份字节码可以产生多个实例对象。

2. 一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示Java类的Class类显示要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。