java lang(Class)

public final class Class<T> implements java.io.Serializable,
                              java.lang.reflect.GenericDeclaration,
                              java.lang.reflect.Type,
                              java.lang.reflect.AnnotatedElement {
    private static final int ANNOTATION= 0x00002000;
    private static final int ENUM      = 0x00004000;
    private static final int SYNTHETIC = 0x00001000;

    private static native void registerNatives();
       static {
        registerNatives();
    }

    private Class() {}

    public String toString() {
        return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
            + getName();
    }
//..........................................

1:Class 类与类的关系

   java程序运行时,系统一直对所有的对象进行所谓的运行时类型标识。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。说白了,Class类对象就是封装了一个类的类型信息,可以通过该对象操作其对应的类,即反射机制。

  Class 类是在Java语言中定义一个特定类的实现。一个类的定义包含成员变量,成员方法,还有这个类实现的接口,以及这个类的父类。Class类的对象用于表示当前运行的 Java 应用程序中的类和接口。Class类提取这些类的一些共同特征,比如说这些类都有类名,都有对应的hashcode,可以判断类型属于class、interface、enum还是annotation。这些可以封装成Class类的域,另外可以定义一些方法,比如获取某个方法、获取类型名等等。这样就封装了一个表示类型(type)的类。程序员可以在程序运行时发现和使用类型信息。

  在java中,每个类都有一个相应的Class对象。也就是说,当编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。Class类的每个实例则代表运行中的一个类。

  Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。 

  虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。虚拟机只会产生一份字节码, 用这份字节码可以产生多个实例对象。

  基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。 每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

  一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象,以下列出几种方式:

public class Test1 {

	public static void main(String[] args) {
		Class<Test1> c = Test1.class;
		System.out.println(c);
		
		Class<?> c1 = null;
		try {
			c1 = Class.forName("com.gdut.lang.classLoader.Test1");
			System.out.println(c1);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			System.out.println("Class not find");
		}
		
		Class<? extends Test1> c2 = new Test1().getClass();
		System.out.println(c2);
		
		if ( ( c != null && c1 != null ) && ( c == c1 ) ) {
			System.out.println("Class对象相等");
		}
	}
}

 打印输出:

   class com.gdut.lang.classLoader.Test1
   class com.gdut.lang.classLoader.Test1
   class com.gdut.lang.classLoader.Test1
   Class对象相等

我们生成的对象都会有个字段记录该对象所属类在CLass类的对象的所在位置。如下图所示:

  我们知道java中有多个加载器,每个加载器能载入多个类,所以只要取得Class类对象,就可利用其getClassLoader()方法取得该类加载器的引用。jvm为每种类管理着独一的Class对象。因此我们可以用双等号操作符来比较对象:a1.getClass()==A.class;应该返回的是true。

 

 

 

 

 

 

 

 

 

 

2.反射机制

定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

>>>>> 与Class类关系

  ava程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。也就是说,ClassLoader找到了需要调用的类时(java为了调控内存的调用消耗,类的加载都在需要时再进行,很抠但是很有效),就会加载它,然后根据.class文件内记载的类信息来产生一个与该类相联系的独一无二的Class对象。该Class对象记载了该类的字段,方法等等信息。以后jvm要产生该类的实例,就是根据内存中存在的该Class类所记载的信息(Class对象应该和我所了解的其他类一样会在堆内存内产生、消亡)来进行。而java中的Class类对象是可以人工自然性的(也就是说开放的)得到的(虽然你无法像其他类一样运用构造器来得到它的实例,因为Class对象都是jvm产生的。不过话说回来,客户产生的话也是无意义的),而且,更伟大的是,基于这个基础,java实现了反射机制。

>>>>> 反射机制功能 

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的方法

  这里需要解释一下:请记住一句话,java中,一切皆对象。也就是说,基本类型int float 等也会在jvm的内存池像其他类型一样中生成一个Class对象。而数组等组合型数据类型也是会生成一个Class对象的,而且更令人惊讶的是,java中数组的本来面目其实就是某个类,惊讶中的惊讶是,含有相同元素的相同维数的数组还会共同享用同一个Class对象! 

 来源:http://blog.csdn.net/ghuilee/article/details/45821537

 

posted @ 2017-09-01 00:28  myseries  阅读(329)  评论(0编辑  收藏  举报