Java从入门到放弃38---Class类

Java从入门到放弃38—Class类

01 Class类概念

Class类是Reflection的根源,针对任何你想动态加载,运行的类,唯有先获得相应的Class对象

在Object类中定义了以下方法,此方法被所有子类继承

public final Class getClass()//返回此 Object 的运行时类。从程序的运行结果来看也很好理解,即:可以通过对象反射求出类的名称。

理解Class:

  • Class本身也是一个类
  • Class只能由系统建立对象
  • 一个加载的类在JVM中只会有一个Class实例
  • 一个Class对象对应的是一个加载到JVM中的.class文件
  • 每个类的实例都会记得自己是由哪个Class实例所声称
  • 通过Class可以完整地得到一个类中的所有被加载的结构
  • Class类是Reflection的根源,针对任何你想动态加载,运行的类,唯有先获得相应的Class对象

哪些类型有Class对象

  • class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类
  • interface:接口
  • []:数组
  • enum:枚举
  • annotation:注解
  • primitive type:基本数据类型
  • void

02 Class类的常用方法

返回值类型 方法名及功能说明
static Class forName(String className) 返回与带有给定字符串名的类或接口相关联的 Class 对象。
static Class forName(String name, boolean initialize, ClassLoader loader) 使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象。
A getAnnotation(Class annotationClass) 如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
Annotation[] getAnnotations() 返回此元素上存在的所有注释。
ClassLoader getClassLoader() 返回该类的类加载器。
Constructor getConstructor(Class... parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
Constructor[] getConstructors() 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
Annotation[] getDeclaredAnnotations() 返回直接存在于此元素上的所有注释。
Constructor getDeclaredConstructor(Class... parameterTypes) 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
Constructor[] getDeclaredConstructors() 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
Field getDeclaredField(String name) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
Field[] getDeclaredFields() 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
Method getDeclaredMethod(String name, Class... parameterTypes) 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method[] getDeclaredMethods() 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
Class getDeclaringClass() 如果此 Class 对象所表示的类或接口是另一个类的成员,则返回的 Class 对象表示该对象的声明类。
Class getEnclosingClass() 返回底层类的立即封闭类。
Constructor getEnclosingConstructor() 如果该 Class 对象表示构造方法中的一个本地或匿名类,则返回 Constructor 对象,它表示底层类的立即封闭构造方法。
Method getEnclosingMethod() 如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回 Method 对象,它表示底层类的立即封闭方法。
T[] getEnumConstants() 如果此 Class 对象不表示枚举类型,则返回枚举类的元素或 null。
Field getField(String name) 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
Field[] *getFields() 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
Class[] getInterfaces() 确定此对象所表示的类或接口实现的接口。
Method getMethod(String name, Class... parameterTypes) 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
Method[] getMethods() 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
int getModifiers() 返回此类或接口以整数编码的 Java 语言修饰符。
String getName()String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
Package getPackage() 获取此类的包。
URL **getResource**(String name) 查找带有给定名称的资源。
T newInstance() 创建此 Class 对象所表示的类的一个新实例。

03 创建运行时类的对象

  • 获取Class类的实例的方式:

    • 若已知具体的类,通过类的class属性获取,该方法最安全可靠,程序性能最高。
    Class clazz = Person.class
    
    • 已知某个类的实例,调用该实例的getClass方法
    Class clazz = person。getClass()
    
    • 已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
    Class clazz = Class。forName("demo01.Student")
    
    • 内置基本数据类型可以直接用类名.Type
    • 还可以利用ClassLoader

小结:

  • 一个类无论创造多少个实例,都只有一个Class对象。
  • 获取Class对象的方法
    • 通过Class.forName(“包名+类名”)只能获取一个Class对象(反射)
    • 通过Object.getClass( )也可以获取一个Class对象(正常创建对象的方式获取Class对象)
    • 通过类的静态成员变量class获得(每个类都有静态成员变量class)
    • 只有默认的基本类型才有的方法:通过静态成员变量Type(被static final修饰)获得(八大基本数据类型:byte int short double float char boolean)
    • 通过Object.getClass.getSuperclass获得父类的类型

程序示例

创建运行时的Class的对象

public class ReflectionTest2 {
    public static void main(String[] args) {
        //1.通过getClass
        Person p1 = new Student();
        Class c1 = p1.getClass();
        System.out.println(c1);
        //2.推荐使用通过forName
        try {
            Class c2 = Class.forName("org.westos.demo2.Person");
            System.out.println(c2);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //3.推荐使用通过静态变量class
        Class c3 = Person.class;
        System.out.println(c3);
        //4.八大基本数据类型独有的方法Type
        Class c4 = Integer.TYPE;
        System.out.println(c4);
        //5.getSuperclass获取父类class
        Class c5 = p1.getClass().getSuperclass();
        System.out.println(c5);
    }
}
class Person{
    String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class Student extends Person{
    public Student(){
        this.name="学生";
    }
}

class Teacher extends Person{
    public Teacher(){
        this.name="教师";
    }
}

运行结果

class org.westos.demo2.Student
class org.westos.demo2.Person
class org.westos.demo2.Person
int
class org.westos.demo2.Person


数组类型一样的情况下,同个维度,只有一个class对象

public class ReflectionTest3 {
    public static void main(String[] args) {
        Class c1 = Object.class;
        Class c2 = Comparable.class;
        Class c3 = Integer.class;
        Class c4 = Void.class;
        Class c5 = ElementType.class;
        Class c6 = Override.class;
        Class c7 = Class.class;
        Class c8 = int[].class;
        Class c9 = int[][].class;
        Class c10 = String[].class;

        System.out.println(c1 );
        System.out.println(c2 );
        System.out.println(c3 );
        System.out.println(c4 );
        System.out.println(c5 );
        System.out.println(c6 );
        System.out.println(c7 );
        System.out.println(c8 );
        System.out.println(c9 );
        System.out.println(c10);

    }
}

运行结果

class java.lang.Object
interface java.lang.Comparable
class java.lang.Integer
class java.lang.Void
class java.lang.annotation.ElementType
interface java.lang.Override
class java.lang.Class
class [I
class [[I
class [Ljava.lang.String;


通过反射获得类名,属性,方法及构造方法

public class ReflectionTest {
    public static void main(String[] args) throws
            ClassNotFoundException {
        //写数组的拷贝类
        Class c1 = Class.forName("java.util.concurrent.CopyOnWriteArrayList");
        //获得类名
        System.out.println(c1.getName());
        System.out.println(c1.getSimpleName());
        //获得属性,成员变量
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("属性:"+declaredField);
        }
        //获得方法
        Method[] declaredMethods = c1.getDeclaredMethods();
        for (Field declaredField : declaredFields) {
            System.out.println("方法:"+declaredField);
        }
        //获得构造方法
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("构造方法:"+constructor);
        }
    }
}

运行结果

java.util.concurrent.CopyOnWriteArrayList
CopyOnWriteArrayList
属性:private static final long java.util.concurrent.CopyOnWriteArrayList.serialVersionUID
属性:final transient java.util.concurrent.locks.ReentrantLock java.util.concurrent.CopyOnWriteArrayList.lock
属性:private transient volatile java.lang.Object[] java.util.concurrent.CopyOnWriteArrayList.array
属性:private static final sun.misc.Unsafe java.util.concurrent.CopyOnWriteArrayList.UNSAFE
属性:private static final long java.util.concurrent.CopyOnWriteArrayList.lockOffset
方法:private static final long java.util.concurrent.CopyOnWriteArrayList.serialVersionUID
方法:final transient java.util.concurrent.locks.ReentrantLock java.util.concurrent.CopyOnWriteArrayList.lock
方法:private transient volatile java.lang.Object[] java.util.concurrent.CopyOnWriteArrayList.array
方法:private static final sun.misc.Unsafe java.util.concurrent.CopyOnWriteArrayList.UNSAFE
方法:private static final long java.util.concurrent.CopyOnWriteArrayList.lockOffset
构造方法:public java.util.concurrent.CopyOnWriteArrayList(java.util.Collection)
构造方法:public java.util.concurrent.CopyOnWriteArrayList()
构造方法:public java.util.concurrent.CopyOnWriteArrayList(java.lang.Object[])


通过反射使用属性,方法及构造方法

public class ReflectionTest2 {
    public static void main(String[] args) throws
            ClassNotFoundException, IllegalAccessException,
            InstantiationException, NoSuchMethodException,
            InvocationTargetException, NoSuchFieldException {
        Class c1 = Class.forName("org.westos.demo4.Student");
        //使用无参构造方法
        Student s1 = (Student) c1.newInstance();
        System.out.println(s1);

        //使用有参构造方法
        Constructor constructor = c1.getConstructor(String.class, int.class);
        Student s2 = (Student) constructor.newInstance("Java", 11);
        System.out.println(s2);
        //使用方法
        Method method = c1.getMethod("setAge", int.class);
        method.invoke(s2,10);
        System.out.println(s2.getAge());
        //使用属性
        Field field1 = c1.getDeclaredField("name");
        Field field2 = c1.getDeclaredField("age");
        // 关闭权限访问检测 , 默认是false[打开的权限访问检测] 如果不关闭可能会发生IllegalAccessException
        field1.setAccessible(true);
        field2.setAccessible(true);
        //通过字段设置值 (对象 , 值)
        field1.set(s1,"JOHN");
        field2.set(s1,23);
        //通过字段获取值
        System.out.println(field1.get(s1)+"|"+field2.get(s1));

    }
}

class Student{
    private String name;
    private int age;
    
    public Student(){
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return this.getName()+"|"+this.getAge();
    }
}

运行结果

null|0
Java|11
10
JOHN|23


你可能感兴趣的:(Java基础)