类的加载机制与反射机制

原创
2020/09/01 22:53
阅读数 28
  • 类的初始化时机《疯狂Java讲义》笔记

Java程序首次通过下面6种方式类使用某个类或接口时,系统就会初始化该类的或接口

  1. 创建类的实例。为某个类创建实例的方式包括:使用new操作符来创建实例,通过反射来创建实例,通过反序列化来创建实例。
  2. 调用某个类的静态方法
  3. 访问某个类或接口的静态Field,或为该静态Field赋值
  4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象。例如:Class.forName(“person”),如果系统还未初始化Person类,则这行代码将会导致Person类被初始化,并返回Person类对应的java.lang.Class对象
  5. 初始化某个类的子类。当初始化某个类的子类时,该子类的所有父类都会被初始化
  6. 世界使用java.exe命令类运行某个主类。当运行某个主类时,程序会先初始化该主类。

 当使用ClassLoader类的loadClass()方法来加载某个类时,该方法只是加载该类,并不会执行该类的初始化。使用Class的forName()静态方法才会导致强制初始化该类。

public class LoaderTest {
    static {
        System.out.print("LoaderTest类的静态初始化块...");
    }
}

public class Main {
    public static void main(String[] args) {
        try {
            LoaderClassTest();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }

    }
    public static  void LoaderClassTest() throws ClassNotFoundException{
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        //下面仅仅是加载LoaderTest类,加载时不会初始化类
        classLoader.loadClass("LoaderTest");
        System.out.print("系统加载LoaderTest类\n");
        //下面的语句会初始化LoaderTest类
        Class.forName("LoaderTest");
    }
}

类的反射:

public class ClassTest {
    private ClassTest(){}
    public ClassTest(String name){
        System.out.print("执行有参数的构造器");
    }
    public void info(){
        System.out.print("执行无参数的info方法");
    }
    public void info(String str){
        System.out.print("执行有参数的info方法"+",其str参数值: "+str);
    }
    class  Inner{}
}

public class Main {
    public static void main(String[] args) {
        Class<ClassTest> classTestClass = ClassTest.class;
        Constructor[] constructors = classTestClass.getDeclaredConstructors();
        System.out.print("ClassTest 的全部构造函数如下: ");
        for (Constructor constructor:constructors){
            System.out.println(constructor);
        }

        Method[] methods = classTestClass.getMethods();
        System.out.println("ClassTest 的全部public方法如下:");
        for (Method method:methods){
            System.out.println(method);
        }
        //或者该Class对象对象所对应类的指定方法
        try {
            System.out.println("ClassTest 里带一个字符串参数的info方法为:"+
                    classTestClass.getMethod("info",String.class));
        }catch (NoSuchMethodException e){
            e.printStackTrace();
        }


    }
}

用反射创建对象

/*
* 通过反射类生成对象有如下两种方式
* 1.使用Class 对象的newInstance()方法来创建该Class对象对应类的实例,这种方式要求该Class对象的对应类
* 有默认构造器,而执行newInstance()方法实际上市利用默认构造器来创建该类的实例
*
* 2.先使用Class对象获取指定的Constructor对象,再调用Constructor 对象的newInstance()方法类创建该Class
* 对象对应的实例。通过这种方式可以选择使用指定的构造器来创建实例
* */
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class ObjectPoolFactory {
    private Map<String,Object> objectPool = new HashMap<>();
    private Object createObject(String className) throws InstantiationException,IllegalAccessException
    ,ClassNotFoundException{
        //forName方法获得Class对象
        Class<?> clazz = Class.forName(className);
        //使用clazz对应类的默认构造器创建实例
        return  clazz.newInstance();
    }
    public void initPool(String fileName) throws InstantiationException,IllegalAccessException
    ,ClassNotFoundException{
        FileInputStream fileInputStream = null;
        try{
            fileInputStream = new FileInputStream(fileName);
            Properties properties = new Properties();
            properties.load(fileInputStream);
            for(String  name:properties.stringPropertyNames()){
                objectPool.put(name,createObject(properties.getProperty(name)));
            }
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                fileInputStream.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }

    }
    public Object getObject(String name){
        return objectPool.get(name);
    }
    public static void main(String[] args) throws  Exception{
        ObjectPoolFactory objectPoolFactory = new ObjectPoolFactory();
        objectPoolFactory.initPool("D:\\MyJavaTest\\TestOne\\src\\obj.txt");
        System.out.println(objectPoolFactory.getObject("a"));
        System.out.println(objectPoolFactory.getObject("b"));
    }
}

构造对象

import java.lang.reflect.Constructor;

public class CreateJFrame {
    /*
    * 使用指定构造器来创建Java对象,需要利用Constructor 对象,步骤如下
    * 1.获取该类的Class对象
    * 2.利用Class对象的getConstructor()方法来获取指定的构造器
    * 3.调用Constructor 的newInstance()方法来创建Java对象
    * */
    public static  void main(String[] args){
        //forName返回Class对象
        try{
            Class<?> jframeClazz = Class.forName("javax.swing.JFrame");
            Constructor constructor = jframeClazz.getConstructor(String.class);
            Object object = constructor.newInstance("测试");
            System.out.println(object);
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }catch (NoSuchMethodException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部