小型教育网站的开发建设论文,为什么要更新网站,自己如何建立一个网站,wordpress 公网Class类简介
在 java 世界里#xff0c;一切皆对象。从某种意义上来说#xff0c;java 有两种对象#xff1a;实例对象和 Class 对象。每个类的运行时的类型信息就是用 Class 对象表示的#xff0c;它包含了与类有关的信息#xff0c;实例对象就是通过 Class 对象来创建的…Class类简介
在 java 世界里一切皆对象。从某种意义上来说java 有两种对象实例对象和 Class 对象。每个类的运行时的类型信息就是用 Class 对象表示的它包含了与类有关的信息实例对象就是通过 Class 对象来创建的。Java 使用 Class 对象执行其 RTTI (运行时类型识别Run-Time Type Identification)多态就是基于 RTTI 实现的。
每一个类都有一个 Class 对象每当编译一个新类就产生一个 Class 对象基本类型 (boolean, byte, char, short, int, long, float, double)有 Class 对象就连关键字 void 也有 Class 对象void.class。Class 对象对应着 java.lang.Class 类如果说类是对象的抽象和集合那么 Class 类就是对类的抽象和集合。
Class 类只有一个私有的构造方法不能通过 new 关键字来创建而是在类加载的时候由 Java 虚拟机以及类加载器来自动构造的。
所有的类都是在对其第一次使用时动态加载到 JVM 中的懒加载。当程序创建第一个对类的静态成员的引用时就会加载这个类。使用 new 创建类对象的时候也会被当作对类的静态成员的引用。因此 java 程序在它开始运行之前并非被完全加载其各个类都是在必需时才加载的。
在类加载阶段类加载器首先检查这个类的 Class 对象是否已经被加载。如果尚未加载默认的类加载器就会根据类的全限定名查找 .class文件。在这个类的字节码被加载时它们会接受验证以确保其没有被破坏并且不包含不良 java 代码。一旦某个类的 Class 对象被载入内存我们就可以它来创建这个类的所有对象。
获取 Class 对象的方式
有三种获得 Class 对象的方式
Class.forName(“类的全限定名”) 实例对象 .getClass() 类名 .class (类字面常量) 第一种方式示例代码如下
public class Dog {static {System.out.println(Loading Dog);}
}public class Cat {static {System.out.println(Loading Cat);}
}public class GetClassSimple {public static void main(String[] args) {Dog dog new Dog();try {Class? cat Class.forName(fanda.zeng.reflect.Cat);Class? dog2 Class.forName(fanda.zeng.reflect.Dog);} catch (ClassNotFoundException e) {System.out.println(can not find class);e.printStackTrace();}}
}输出
Loading Dog
Loading Cat上述的 static{} 代码块只会在第一次加载类的时候被调用由输出结果得知new 对象和调用Class.forName 时会判断类是否已经加载没有加载则会调用类加载器来加载类已经加载过了不会重复加载。Class.forName 的好处就在于不需要为了获得 Class 引用而持有该类型的对象只要通过全限定名就可以返回该类型的一个 Class 引用。
第二种方式示例代码如下
Dog dog new Dog();
Class? clazz dog.getClass();输出
Loading Dog如果你已经有了该类型的对象那么我们就可以通过调用 getClass() 方法来获取 Class 引用了这个方法属于根类 Object 的一部分它返回的是表示该对象的实际类型的 Class 引用。因为 new 操作已经把类加载到内存了所有 getClass 方法不会再去执行类加载了而是直接从 java 堆中返回该类型的 Class 引用。
第三种方式示例代码如下
Class c1 Integer.class;
Class c2 int.class;
Class c3 Integer.TYPE;Class dog Dog.class;
Class cat Cat.class;System.out.println(c1);
System.out.println(c2);
System.out.println(c3);输出
class java.lang.Integer
int
int这种方式在编译时就会受到检查(因此不需要置于try语句块中)不仅可以应用于普通的类也可以应用于接口、数组及基本数据类型。上述 c2 等价于 c3 因为在包装类中有个一个字段 TYPE TYPE 字段是一个引用指向对应的基本数据类型的 Class 对象因此不只 Integer 包装类其他 7 种包装类以及 Void 类型都有对应的 TYPE 字段。
注意上述代码没有打印 Dog 和 Cat 静态代码块的内存因为用 .class 来创建 Class 对象的引用时不会自动地初始化该 Class 对象类加载被延迟到了对静态方法或者非常数静态域首次引用时才执行。示例代码如下
public class Dog {static final String DOG_CONSTANT DOG_CONSTANT;static String staticValue dog_staticValue;static {System.out.println(Loading Dog);}
}Class dog Dog.class;
System.out.println( 常量 );
System.out.println(Dog.DOG_CONSTANT);
System.out.println( 静态成员 );
System.out.println(Dog.staticValue);输出 常量
DOG_CONSTANT静态成员
Loading Dog
dog_staticValue由输出结果可知当引用 staticValue 时类被加载到内存并执行了静态代码块的内容。因为被 static final 修饰的属性在编译期就把结果放入常量池了所以引用的时候并不需要类真正地被加载。但是如果只是将一个域设置为 static 或 final 的还不足以确保这种行为此时引用会强制加载并初始化类。
Class 对象的唯一性
每个通过关键字 class 标识的类在内存中有且只有一个与之对应的 Class 对象来描述其类型信息不论通过哪种方式获得该类的 Class 对象它们返回的都是指向同一个 java 堆地址上的 Class 引用jvm 不会创建两个相同类型的 Class。也就是说无论创建多少个实例对象其依据的都是同一个 Class 对象。java 虚拟机中使用双亲委派模型来组织类加载器之间的关系来保证 Class 对象的唯一性。验证代码如下
Class dog Dog.class;
Class dog2 Class.forName(fanda.zeng.reflect.Dog);
Class dog3 new Dog().getClass();
Class dog4 new Dog().getClass() ;if (dog dog2 dog2 dog3 dog3 dog4) {System.out.println(true);
} else {System.out.println(false);
} 输出结果为 true 表示都是同一个堆上的 Class 引用。
Class 类的方法
先说明一下构造方法都是获取本类的(一定不包括父类)只是公共和其他修饰符的区别。以下其他带有 Declared 的方法都表示只能获取本类的属性(不包括父类的)不过可以获取所有修饰符修饰的属性(公有保护默认私有)。不带有 Declared 的方法可以获取本类及父类的所有的属性不过只能获取 公有 修饰符的 。
获取构造函数
//返回 Constructor 对象数组
Constructor?[] getDeclaredConstructors()
Constructor?[] getConstructors() // 返回指定参数的 Constructor 对象
ConstructorT getConstructor(Class?... parameterTypes)
ConstructorT getDeclaredConstructor(Class?... parameterTypes) 获取成员变量
// 返回 Field 对象数组
Field[] getFields()
Field[] getDeclaredFields() // 返回指定的 Field 对象
Field getField(String name)
Field getDeclaredField(String name) 获取成员方法
// 返回 Method 对象数组
Method[] getMethods()
Method[] getDeclaredMethods() / 返回指定的 Method 对象
Method getMethod(String name, Class?... parameterTypes)
Method getDeclaredMethod(String name, Class?... parameterTypes) 获取注解方法
// 返回指定 Annotation 对象
public A extends Annotation A getDeclaredAnnotation(ClassA annotationClass) {
public A extends Annotation A getAnnotation(ClassA annotationClass) {// 返回 Annotation 对象数组
Annotation[] getDeclaredAnnotations()
public Annotation[] getAnnotations ()创建对象的方法
// 创建此 Class 对象所表示的类的一个新实例
T newInstance() 返回字符串(String)的方法
// 返回底层类的规范化名称
String getCanonicalName() // 返回全限定名(全限定名包名.类名)
String getName() // 返回源代码中给出的底层类的简称
String getSimpleName() 返回 boolean 的方法
// 判断是不是局部类也就是方法里面的类
boolean isLocalClass() // 判断是不是成员内部类也就是一个类里面定义的类
boolean isMemberClass() // 判断当前类是不是匿名类匿名类一般用于实例化接口
boolean isAnonymousClass() // 如果指定类型的注释存在于此元素上
isAnnotationPresent (Class? extends Annotation annotationClass)// 判断当前Class对象是否是注释类型
boolean isAnnotation() ;// 判断该类是否是枚举类
boolean isEnum() // 判断指定的 Object 是否 Class 的实例
boolean isInstance(Object obj) // 判断指定的 Class 对象是否表示一个接口类型
boolean isInterface() // 判断指定的 Class 对象是否表示一个基本类型
boolean isPrimitive() 获取 Class 的修饰符
//返回此类或接口以整数编码的 Java 语言修饰符。
public int getModifiers()修饰符是java.lang.reflect.Modifier的静态属性。对应表如下PUBLIC: 1
PRIVATE: 2
PROTECTED: 4
STATIC: 8
FINAL: 16
SYNCHRONIZED: 32
VOLATILE: 64
TRANSIENT: 128
NATIVE: 256
INTERFACE: 512
ABSTRACT: 1024
STRICT: 2048我们可以使用 Class.getModifiers() 获得调用类的修饰符的二进制值然后使 用 Modifier.toString(int modifiers) 将获取到的二进制值转换为字符串。
代码示例
// 动物类
public class Animal {private int mAnimalPrivate;protected int mAnimalProtected;public int mAnimalpublic;public Animal() {}public Animal(int mAnimalPrivate) {this.mAnimalPrivate mAnimalPrivate;}public Animal(int mAnimalPrivate, int mAnimalProtected) {this.mAnimalPrivate mAnimalPrivate;this.mAnimalProtected mAnimalProtected;}public Animal(int mAnimalPrivate, int mAnimalProtected, int mAnimalpublic) {this.mAnimalPrivate mAnimalPrivate;this.mAnimalProtected mAnimalProtected;this.mAnimalpublic mAnimalpublic;}public void animalPublic() {System.out.println(Method : animalPublic);}private void animalPrivate() {System.out.println(Method : animalPrivate);}protected void animalProtected() {System.out.println(Method : animalProtected);}}// 猫类继承动物类
public class Cat extends Animal {static {System.out.println(Loading Cat);}private int mCatPrivate;protected int mCatProtected;public int mCatpublic;public Cat() {}public Cat(int mCatPrivate) {this.mCatPrivate mCatPrivate;}private Cat(int mCatPrivate, int mCatProtected) {this.mCatPrivate mCatPrivate;this.mCatProtected mCatProtected;}public void catPublic() {System.out.println(Method : catPublic);}private void catPrivate() {System.out.println(Method : catPrivate);}protected void catProtected() {System.out.println(Method : catProtected);}Overridepublic String toString() {return mCatPrivate mCatPrivate ----------- mCatProtected mCatProtected ----------- mCatpublic mCatpublic;}
}获取构造函数示例 public static void main(String[] args) throws Exception {Class clazz Cat.class;System.out.println(获取本类所有 public 构造方法);for (Constructor constructor : clazz.getConstructors()) {System.out.println(constructor.toString());}System.out.println();System.out.println(获取本类所有构造方法);for (Constructor declaredConstructor : clazz.getDeclaredConstructors()) {System.out.println(declaredConstructor.toString());}System.out.println();System.out.println(这里获取指定的带有两个参数的私有构造方法);Constructor privateConstructor clazz.getDeclaredConstructor(int.class, int.class);System.out.println(privateConstructor.toString());// 改变访问权限privateConstructor.setAccessible(true);Cat cat (Cat) privateConstructor.newInstance(1, 2);System.out.println(cat.toString());System.out.println();System.out.println(这里获取指定的带有一个参数的公有构造方法);Constructor publicConstructor clazz.getConstructor(int.class);System.out.println(publicConstructor.toString());Cat cat2 (Cat) publicConstructor.newInstance(100);System.out.println(cat2.toString());
}输出
获取本类所有 public 构造方法
public fanda.zeng.reflect.Cat(int)
public fanda.zeng.reflect.Cat()获取本类所有构造方法
private fanda.zeng.reflect.Cat(int,int)
public fanda.zeng.reflect.Cat(int)
public fanda.zeng.reflect.Cat()这里获取指定的带有两个参数的私有构造方法
private fanda.zeng.reflect.Cat(int,int)
Loading Cat
mCatPrivate 1-----------mCatProtected 2-----------mCatpublic 0这里获取指定的带有一个参数的公有构造方法
public fanda.zeng.reflect.Cat(int)
mCatPrivate 100-----------mCatProtected 0-----------mCatpublic 0获取成员变量示例
public static void main(String[] args) throws Exception {Class clazz Cat.class;System.out.println(获取所有 public 成员变量);for (Field field : clazz.getFields()) {System.out.println(field.toString());}System.out.println();System.out.println(获取本类所有成员变量);for (Field field : clazz.getDeclaredFields()) {System.out.println(field.toString());}System.out.println();System.out.println(这里获取指定名字的成员变量);Field mCatPrivateField clazz.getDeclaredField(mCatPrivate);System.out.println(mCatPrivateField.toString());// 改变访问权限mCatPrivateField.setAccessible(true);Cat cat new Cat();mCatPrivateField.set(cat, 100);System.out.println(cat.toString());}输出
获取所有 public 成员变量
public int fanda.zeng.reflect.Cat.mCatpublic
public int fanda.zeng.reflect.Animal.mAnimalpublic获取本类所有成员变量
private int fanda.zeng.reflect.Cat.mCatPrivate
protected int fanda.zeng.reflect.Cat.mCatProtected
public int fanda.zeng.reflect.Cat.mCatpublic这里获取指定名字的成员变量
private int fanda.zeng.reflect.Cat.mCatPrivate
Loading Cat
mCatPrivate 100-----------mCatProtected 0-----------mCatpublic 0获取成员方法示例
public static void main(String[] args) throws Exception {Class clazz Cat.class;System.out.println(获取所有 public 成员方法);for (Method method : clazz.getMethods()) {System.out.println(method.toString());}System.out.println();System.out.println(获取本类所有成员方法);for (Method method : clazz.getDeclaredMethods()) {System.out.println(method.toString());}System.out.println();System.out.println(这里获取指定名字的成员方法);Method catPrivateMethod clazz.getDeclaredMethod(catPrivate);System.out.println(catPrivateMethod.toString());// 改变访问权限catPrivateMethod.setAccessible(true);Cat cat new Cat();catPrivateMethod.invoke(cat);
}输出
获取所有 public 成员方法
public java.lang.String fanda.zeng.reflect.Cat.toString()
public void fanda.zeng.reflect.Cat.catPublic()
public void fanda.zeng.reflect.Animal.animalPublic()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()获取本类所有成员方法
public java.lang.String fanda.zeng.reflect.Cat.toString()
public void fanda.zeng.reflect.Cat.catPublic()
protected void fanda.zeng.reflect.Cat.catProtected()
private void fanda.zeng.reflect.Cat.catPrivate()这里获取指定名字的成员方法
private void fanda.zeng.reflect.Cat.catPrivate()
Loading Cat
Method : catPrivate上述获取所有公共方法时包括本类及所有的父类的公共方法都会查找出来。