package com.cry;
class Dog {
static final String s1 = "Dog_s1";
static String s2 = "Dog_s2";
static {
System.out.println("Loading Dog");
}
}
class Cat {
static String s1 = "Cat_s1";
static {
System.out.println("Loading Cat");
}
}
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
System.out.println("----Star Dog----");
Class dog = Dog.class;
System.out.println("------");
System.out.println(Dog.s1);
System.out.println("------");
System.out.println(Dog.s2);
System.out.println("---start Cat---");
Class cat = Class.forName("com.cry.Cat");
System.out.println("-------");
System.out.println(Cat.s1);
System.out.println("finish main");
}
}
/* Output:
----Star Dog----
------
Dog_s1
------
Loading Dog
Dog_s2
---start Cat---
Loading Cat
-------
Cat_s1
finish main
*/
从上面我们可以看到,如果仅使用.class语法来获得对类的Class引用是不会引发初始化的。但是如果使用Class.forName来产生引用,就会立即进行了初始化,就像Cat所看到的。
如果一个字段被static final修饰,我们称为”编译时常量“,就像Dog的s1字段那样,那么在调用这个字段的时候是不会对Dog类进行初始化的。因为被static和final修饰的字段,在编译期就把结果放入了常量池中了。但是,如果只是将一个域设置为static 或final的,还不足以确保这种行为,就如调用Dog的s2字段后,会强制Dog进行类的初始化,因为s2字段不是一个编译时常量。
一旦类被加载了到了内存中,那么不论通过哪种方式获得该类的Class对象,它们返回的都是指向同一个java堆地址上的Class引用。jvm不会创建两个相同类型的Class对象
使用通配符,它是Java泛型的一部分。通配符的符合是”?“,表示“任何事物“:
Class<? extends Number> c1 = Integer.class;
c1 = Number.class;
c1 = Double.class;

public interface T1 {
}
public interface T2 {
}
public class Cell {
public int mCellPublic;
}
public class Animal extends Cell {
private int mAnimalPrivate;
protected int mAnimalProtected;
int mAnimalDefault;
public int mAnimalPublic;
private static int sAnimalPrivate;
protected static int sAnimalProtected;
static int sAnimalDefault;
public static int sAnimalPublic;
}
public class Dog extends Animal implements T1, T2 {
private int mDogPrivate;
public String mDogPublic;
protected String mDogProtected;
private int mDogDefault;
private static int sDogPrivate;
protected static int sDogProtected;
static int sDogDefault;
public static Double sDogPublic;
}
public class Test {
public static void main(String[] args) {
Class<Dog> dog = Dog.class;
for(Field field : dog.getFields()){
//获取Dog类的所有字段名,包含父类以及父类的父类...
System.out.println(field.getName());
}
System.out.println("------------1-------------");
for(Field field : dog.getFields()){
//获取Dog类的所有字段的类型
System.out.println(field.getType().getName());
}
System.out.println("------------2-------------");
for(Field field : dog.getDeclaredFields()){
//获取Dog类的自己的所有成员字段名
System.out.println(field.getName());
}
}
}
运行结果:
mDogPublic
sDogPublic
mAnimalPublic
sAnimalPublic
mCellPublic
------------1-------------
java.lang.String
java.lang.Double
int
int
int
------------2-------------
mDogPrivate
mDogPublic
mDogProtected
mDogDefault
sDogPrivate
sDogProtected
sDogDefault
sDogPublic
Process finished with exit code 0
网友评论