zoukankan      html  css  js  c++  java
  • Java反射——java.lang.Class和类的加载

    反射的基础: java.lang.Class

    Class类的实例对象,用于记录类描述信息。
    源码说:represent classes and interfaces in a running Java application

    Class类没有公共的构造方法,无法通过new运算符实例化;只能通过对象的getClass方法,或是通过Class.forName(…)来获得实例。

    static ClassforName(String className)throws ClassNotFoundException 使用参数className来指定具体的类,来获得相关的类描述对象,该方法有可能抛出类加载异常(ClassNotFoundException),必须捕捉
    Class getSuperclass() 获得当前类描述对象的父类的描述对象
    String getName() 返回当前类描述对象的类名称

    获取Class对象的三种方式:

    public class _T11获取Class {
    	// Class:类描述对象
    	// (源码说:represent classes and interfaces in a running Java application)
    	public static void main(String[] args) {
    		Class<?> _class;
    		// ***1*对象.getClass()
    		String str = "";
    		_class = str.getClass();
    		System.out.println(_class + "-----对象名.getClass()");
    		// ***2*类.class
    		_class = String.class;
    		System.out.println(_class + "-----类名.class");
    		// ***3*Class.forName("")
    		try {
    			_class = Class.forName("java.lang.String");
    			System.out.println(_class + "-----Class.forName(...)");
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    class java.lang.String-----对象名.getClass()
    class java.lang.String-----类名.class
    class java.lang.String-----Class.forName(...)

    .getSuperclass()

    _class.getSuperclass():获得父类的描述对象

    以下示例,打印StringBuffer的父类、父类的父类……

    public class _T12getSuperclass {
    	public static void main(String[] args) {
    		System.out.println("-----.getSuperclass()获得父类的描述对象-----");
    		try {
    			Class _class = Class.forName("java.lang.StringBuffer");
    			// 循环打印父类信息,直到没有父类
    			while (_class != null) {
    				System.out.println(_class);
    				// getSuperclass():获得父类的描述对象
    				_class = _class.getSuperclass();
    			}
    		} catch (ClassNotFoundException cnfe) {
    			cnfe.printStackTrace();
    		}
    	}
    }
    

    -----.getSuperclass()获得父类的描述对象-----
    class java.lang.StringBuffer
    class java.lang.AbstractStringBuilder
    class java.lang.Object

    类的加载

    Java程序运行在Java虚拟机进程中,同一个JVM的所有线程、所有变量都处于同一个进程里。
    当系统出现以下几种情况时,JVM进程将被终止:
    |--程序正常结束。
    |--程序运行到System.exit()或Runtime.getRuntime().exit()代码。
    |--程序执行过程中遇到未捕获的异常或错误。
    |--强制结束JVM进程。

    类加载,是指将类的.class文件读入内存,并为之创建一个java.lang.Class对象。

    class Tester {
    	static {
    		System.out.println("静态初始化块...");
    	}
    	public Tester() {
    		System.out.println("构造方法...");
    	}
    }
    public class _T21TestClassLoader {
    	public static void main(String[] args) throws ClassNotFoundException {
    		ClassLoader _cLoader = ClassLoader.getSystemClassLoader();
    		System.out.println("=====loadClass():加载类,但不做初始化=====");
    		String _包类名 = "Tester";
    		Class<?> loadClass = _cLoader.loadClass(_包类名);
    		System.out.println("加载即得Class:" + loadClass);
    		// -----------------------------------------------------
    		System.out.println("=====Class.forName():初始化(静态代码块执行)=====");
    		Class.forName(_包类名);
    	}
    }
    

    =loadClass():加载类,但不做初始化=
    加载即得Class:class Tester
    =Class.forName():初始化=
    静态初始化块...

    static变量的初始化

    使用static final的变量(常量),如果值可以在编译期确定,则类不需要初始化。

    // static final修饰的变量,被用于“常量”,更类似于“宏定义”。
    // 当其在编译器能确定时,不需要初始化类,使用“宏变量”替换的形式进行编译;
    // 当其不能在编译期确定时,需要初始化类;
    // 如果未加final,不是“宏定义”,需要初始化类。
    class StaticField {
    	static {
    		System.out.println("---此代码不执行---");
    	}
    	static final String compileConstant = "static final变量,编译时能确定,类不做初始化,使用'宏替换'的形式编译";
    }
    class StaticField2 {
    	static {
    		System.out.println("【2:此代码执行,表示初始化过了】");
    	}
    	static final String compileConstant = "static final变量,编译时不能确定时,运行时才确定。"
    			+ System.getProperty("os.name");
    }
    class StaticField3 {
    	static {
    		System.out.println("【3:此代码执行,因为就不是final】static{}变量不是final,编译时能确定,变量");
    	}
    	static String compileConstant = "非final的static变量";
    }
    public class _T22宏定义常量 {
    	public static void main(String[] args) {
    		System.out.println("	" + StaticField.compileConstant);
    		System.out.println("	" + StaticField2.compileConstant);
    		System.out.println("	" + StaticField3.compileConstant);
    	}
    }
    

    运行结果:

    	static final变量,编译时能确定,类不做初始化,使用'宏替换'的形式编译
    【2:此代码执行,表示初始化过了】
    	static final变量,编译时不能确定时,运行时才确定。Windows 10
    【3:此代码执行,因为就不是final】static{}变量不是final,编译时能确定,变量
    	非final的static变量
    
  • 相关阅读:
    100 道 Linux 常见面试题
    借助Redis锁,完美解决高并发秒杀问题
    'cnpm'安装install
    Git常用命令及方法大全
    idea controller service impl mapper xml切换跳转快捷键
    idea创建springboot项目用阿里云镜像
    mybatis.type-aliases-package的作用和用法
    MyBatis Generator
    https://antdv.com/components/layout-cn/
    https://mvnrepository.com/search?q=mysql-connector-java //maven
  • 原文地址:https://www.cnblogs.com/tigerlion/p/11182840.html
Copyright © 2011-2022 走看看