一.类的加载:
在jvm虚拟机在运行时,会直接去加载main函数。
当类中存在继承关系时,子类调用静态常量,只会加载mian,父类子类并不会去进行加载。
详情代码如下:
package FanShe;
public class Test06 {
static {
System.out.println("main类被加载!");
}
public static void main(String[] args) throws ClassNotFoundException {
//主动引用
// Son son = new Son();
//反射也会产生主动引用
// Class.forName("FanShe.Son");
//不会产生类引用的方法
System.out.println(Son.b);//不会加载子类
//常量不会让父类与子类进行加载
// System.out.println(Son.M);//只有main类被加载,因为常量在链接阶段就已经存入到调用类的常量池中了。
}
}
class Father{
static int b = 2;
static {
System.out.println("父类被加载!");
}
}
class Son extends Father{
static {
System.out.println("子类被加载!");
m=300;
}
static int m = 100;
static final int M = 1;
}
运行结果:
总结:
只有在new对象的过程中,或者在反射的过程中,才会产生主动引用,让类进行初始化。
调用常量时,类不会进行加载,因为在链接阶段时查那个良就已经存入到调用类的常量池中了。
子类调用父类常量时,父类会被加载,但是子类不会被加载。
类的主动引用一定产生类的初始化,类的被动引用不会产生类的初始化。
jvm虚拟机启动时就回去加载main函数。
二.反射的应用方法:
当我们获取类的class对象后,可以通过Class类的方法来获取User(举例)类中的数据,详情可参考jdk手册(Class)。
package FanShe;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test07 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException {
Class<?> c1 = Class.forName("FanShe.User");
//获得类的名字
System.out.println(c1.getName());//获取c1包名+类名
System.out.println(c1.getSimpleName());//获取c1类名
//获得类的对象
System.out.println("-------------------------------------------------------------------------------------------");
Object o = c1.newInstance();// c1.newInstance()获取User对象
System.out.println(o);
//获得类的属性
System.out.println("-------------------------------------------------------------------------------------------");
Field[] fields = c1.getFields();//只能够获取User类的public属性
for (Field field : fields) {
System.out.println(field);
}
System.out.println("-------------------------------------------------------------------------------------------");
Field[] declaredFields = c1.getDeclaredFields();//获取User类的所有属性
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
System.out.println("-------------------------------------------------------------------------------------------");
Field name = c1.getDeclaredField("name");//获取User类的指定属性,这里的方法没有s
System.out.println(name);
//获得类的方法
System.out.println("-------------------------------------------------------------------------------------------");
Method[] methods = c1.getMethods();//获取本类及其父类的全部方法
for (Method method : methods) {
System.out.println("正常的:"+method);
}
System.out.println("-------------------------------------------------------------------------------------------");
Method[] declaredMethods = c1.getDeclaredMethods();//获得本类的方法
for (Method declaredMethod : declaredMethods) {
System.out.println("本类的:"+declaredMethod);
}
//**为什么获取本类方法的时候会需要参数,原因就是因为方法重载(方法名一致但参数不同),通过参数来区分。
System.out.println("-------------------------------------------------------------------------------------------");
Method name1 = c1.getDeclaredMethod("getName",null);//获取本类的指定方法
Method setName = c1.getDeclaredMethod("setName", String.class);
System.out.println(name1);
System.out.println(setName);
//获得类的构造器
System.out.println("-------------------------------------------------------------------------------------------");
Constructor<?>[] constructors = c1.getConstructors();//获得所有构造方法
for (Constructor<?> constructor : constructors) {
System.out.println("公共构造:"+constructor);
}
System.out.println("-------------------------------------------------------------------------------------------");
Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();//获得本类构造方法
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println("本类构造:"+declaredConstructor);
}
System.out.println("-------------------------------------------------------------------------------------------");
Constructor<?> declaredConstructor = c1.getDeclaredConstructor(String.class,String.class);//获得本类指定构造方法
System.out.println("指定构造:"+declaredConstructor);
}
}
//13
运行结果:
获取类的名称:(包名+类名,类名) 方法:getName() , getSimpleName()
获取类的对象: 方法:newInstance()
获取类的属性: 方法:getFields() , getDeclareFields() , getDeclareField()
获取类的方法: 方法:getMethods() , getDeclareMethods() ,
获取类的指定方法: 方法:getDeclareMethod()
获取类的构造器: 方法:getConstructors() , getDeclaredConstructors() , getDeclaredConstructor()
小白学习笔记,可能存在错误,希望大佬指点!!