- 类的初始化时机《疯狂Java讲义》笔记
当Java程序首次通过下面6种方式类使用某个类或接口时,系统就会初始化该类的或接口
- 创建类的实例。为某个类创建实例的方式包括:使用new操作符来创建实例,通过反射来创建实例,通过反序列化来创建实例。
- 调用某个类的静态方法
- 访问某个类或接口的静态Field,或为该静态Field赋值
- 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象。例如:Class.forName(“person”),如果系统还未初始化Person类,则这行代码将会导致Person类被初始化,并返回Person类对应的java.lang.Class对象
- 初始化某个类的子类。当初始化某个类的子类时,该子类的所有父类都会被初始化
- 世界使用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();
}
}
}