对Class类的几点探索

java程序的运行过程中,所有的类和接口都会成为一个实例,即一个Class类的对象,所有的类(如enum)、接口(如annotation)、数组、基本数据类型和void类型都代表着Class对象。

Class没有公共的构造器,它是由JVM在加载类或者在类的加载器中调用方法时被自动构造出来的。

一、几点额外知识

enum:enum是一种数据类型(枚举类型)枚举类型定义的一般形式为:enum枚举名枚举值 };

Exp: 

public class EnumDemo{
<span style="white-space:pre">	</span>private enum Seasons{
<span style="white-space:pre">		</span>winter,spring,summer,fall
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>public static void main(String[]args){
<span style="white-space:pre">		</span>for(Seasons s:Seasons.values()){
<span style="white-space:pre">			</span>System.out.println(s);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}
}

 
 

annotation: 提供一些本来不属于程序的数据,比如:一段代码的作者或者告诉编译器禁止一些特殊的错误。An annotation 对代码的执行没有什么影响。Exp:   @Deprecated

native关键字:A native method is a Java method whose implementation is provided by non-java code.

final关键字:不能被继承,锁定该方法

   transient关键字:

1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。

2transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。

3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。

volatile:程度较轻的 synchronized

二、对Class的初步认识

首先,Class.class中给出了一个简单的例子,应用了Class的对象来打印一个对象的类名:
void printClassName(Object obj) {
         System.out.println("The class of " + obj +" is " + obj.getClass().getName());
 }
下面 简单介绍一下Class对象获取的三种方式:
1)如例子所示,采用object类中的getClass方法来实现。
2)使用Class类中的forName()方法来获得对应的Class对象。exp:Class.forName("Foo")
3)如果T是java中的类型名,那么直接采用T.class的方式。exp:double.class

三、Class的常用方法

1.forName()根据名称获取相应的Class对象
2.newInstance()创建一个实例
exp:
public void exp() throws InstantiationException, IllegalAccessException{
		String r;
		r.getClass().newInstance();
}
3.isInstance() 与之相似的还有isInterface()等等
4.getName()获取Class对象的全名
5.getClassLoader()获取类的加载器
6.getSuperclass()获取父类的Class 与之相似的还有getPackage()等
7.getComponentType()返回数组组件类型的Class
8.getSimpleName()得到简称
9.getMethods()返回一个类中的所有方法
exp:
public class ClassDemo {

   public static void main(String[] args) {

     try {
        Class cls = Class.forName("java.awt.Label");
        System.out.println("Methods =");
        Method m[] = cls.getMethods();
        for(int i = 0; i < m.length; i++) {
           System.out.println(m[i]);
        }
     } 
     catch (Exception e) {
        System.out.println("Exception: " + e);
     }
   }
} 
10.Class中原子操作支持(源码,未仔细研究):
    private static class Atomic {
        // initialize Unsafe machinery here, since we need to call Class.class instance method
        // and have to avoid calling it in the static initializer of the Class class...
        private static final Unsafe unsafe = Unsafe.getUnsafe();
        // offset of Class.reflectionData instance field
        private static final long reflectionDataOffset;
        // offset of Class.annotationType instance field
        private static final long annotationTypeOffset;

        static {
            Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches
            reflectionDataOffset = objectFieldOffset(fields, "reflectionData");
            annotationTypeOffset = objectFieldOffset(fields, "annotationType");
        }

        private static long objectFieldOffset(Field[] fields, String fieldName) {
            Field field = searchFields(fields, fieldName);
            if (field == null) {
                throw new Error("No " + fieldName + " field found in java.lang.Class");
            }
            return unsafe.objectFieldOffset(field);
        }

        static <T> boolean casReflectionData(Class<?> clazz,
                                             SoftReference<ReflectionData<T>> oldData,
                                             SoftReference<ReflectionData<T>> newData) {
            return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData);
        }

        static <T> boolean casAnnotationType(Class<?> clazz,
                                             AnnotationType oldType,
                                             AnnotationType newType) {
            return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType);
        }
    }

四、一些小细节

1.getSimpleName()中:
        while (index < length && isAsciiDigit(simpleName.charAt(index)))
            index++;
        // Eventually, this is the empty string iff this is an anonymous class
        return simpleName.substring(index);
index<length起到了防止charAt溢出的作用。

2.可以使用==操作符对类进行比较:e.getClass() == Example.class
3.forName和newInstance结合使用,可以根据类名创建对象:
Object obj = Class.forName(s).newInstance()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值