反射的基础: 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("\t" + StaticField.compileConstant);
System.out.println("\t" + StaticField2.compileConstant);
System.out.println("\t" + StaticField3.compileConstant);
}
}

运行结果:

	static final变量,编译时能确定,类不做初始化,使用'宏替换'的形式编译
【2:此代码执行,表示初始化过了】
static final变量,编译时不能确定时,运行时才确定。Windows 10
【3:此代码执行,因为就不是final】static{}变量不是final,编译时能确定,变量
非final的static变量

Java反射——java.lang.Class和类的加载的更多相关文章

  1. (六)《Java编程思想》——初始化及类的加载顺序

    package chapter7; /** * 初始化及类的加载顺序:顺序如下 * 1.基类的static变量 * 2.导出类的static变量 * 3.基类的变量 * 4.基类的构造函数 * 5.导 ...

  2. Java程序设计19——类的加载和反射-Part-B

    接下来可以随意提供一个简单的主类,该主类无须编译就可使用上面的CompileClassLoader来运行它. package chapter18; public class Hello { publi ...

  3. Java的静态代码块是否会在类被加载时自动执行?

    JAVA静态代码块会在类被加载时自动执行? 一.先看Java静态方法,静态变量 http://www.cnblogs.com/winterfells/p/7906078.html 静态代码块 在类中, ...

  4. JVM虚拟机系列(一)类的加载

    JAVA虚拟机系列(一) 类的加载 目录 1 类的初始化过程 2 详解初始化时的各个阶段 一.类初始化的过程 先来看一个CLASS文件在整体生命周期里会遇到的阶段: xxxx.class ---> ...

  5. java 27 - 1 反射之 类的加载器

    说到反射,首先说类的加载器. 类的加载: 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. 加载: 就是指将class文件读入内存,并为之 ...

  6. Java程序设计19——类的加载和反射-Part-A

    1 本文概要 本章介绍Java类的加载.连接和初始化的深入知识,并重点介绍Java反射相关的内容.本章知识偏底层点,这些运行原理有助于我们更好的把我java程序的运行.而且Java类加载器除了根加载器 ...

  7. Java基础_类的加载机制和反射

    类的使用分为三个步骤: 类的加载->类的连接->类的初始化 一.类的加载 当程序运行的时候,系统会首先把我们要使用的Java类加载到内存中.这里加载的是编译后的.class文件 每个类加载 ...

  8. java 反射,类的加载过程以及Classloader类加载器

    首先自定义一个类Person package reflection; public class Person { private String name; public int age; public ...

  9. 【转】怎么解决java.lang.NoClassDefFoundError错误 ,以及类的加载机制

    转自http://blog.csdn.net/jamesjxin/article/details/46606307 前言 在日常Java开发中,我们经常碰到java.lang.NoClassDefFo ...

随机推荐

  1. Django前后端安全验证

    会话技术 关注公众号"轻松学编程"了解更多. 1.Cookie 客户端会话技术(数据存储在客户端) 以key-value的形式进行存储 cookie的操作都是通过Response来 ...

  2. git版本管理系统使用

    版本管理系统Git 关注公众号"轻松学编程"了解更多. git下载链接:https://pan.baidu.com/s/12vJn-K0lK9XlkVQbNe8S-A 密码:m4m ...

  3. LR逻辑回归附代码

    参考https://zhuanlan.zhihu.com/p/74874291 import pandas as pdpd.set_option('display.max_columns', 500) ...

  4. SpringBoot第九集:整合JSP和模板引擎Freemarker/Thymeleaf(2020最新最易懂)

    SpringBoot第九集:整合JSP和模板引擎(2020最新最易懂) 当客户通过前端页面提交请求后,我们以前是怎么做的?后端接收请求数据,处理请求,把响应结果交给模板引擎JSP,最后将渲染后的JSP ...

  5. 解决git push出现error: failed to push some refs to 错误

    错误截图 背景 码云上创建了空项目 本地项目绑定了远程仓库,尝试git push,然后报了错 解决办法 使用强制命令git pull origin master --allow-unrelated-h ...

  6. .Net 5 正式版RTM 发布

    下载连接 https://dotnetcli.azureedge.net/dotnet/Sdk/5.0.100-rtm.20515.8/dotnet-sdk-5.0.100-rtm.20515.8-w ...

  7. 阅源-jdk8-FunctionalInterface注解

    package java.lang; import java.lang.annotation.*; /** * An informative annotation type used to indic ...

  8. [MIT6.006] 4. Heaps and Heap Sort 堆,堆排序

    第4节课仍然是讲排序,但介绍的是一种很高效的堆排序. 在编程过程中,有时候会需要进行extrat_max的操作,即从一个数列里挨个抽取最大值并将其它从原数列中移除.而排序问题也可以看作是一个extra ...

  9. JAVA内存模型和Happens-Before规则

    前言 上一篇文章王子给大家介绍了并发编程中比较关心的三个核心问题,可见性.有序性和原子性. 今天我们继续来探索并发编程的内容,聊一聊JAVA的内存模型和Happens-Before规则. JAVA内存 ...

  10. Linux 笔记2

    1.linux的usr目录相当于windows下Program Files目录,存放的应用程序2.在centos 6.4按ctrl+alt+F2切换到命令行,ctr+alt+F8切换到图像界面,ctr ...