在一些应用中,无法事先知道使用者将加载什么类,而必须让使用者指定类名称以加载类,可以使用 Class 的静态 forName() 方法实现动态加载类。下面的范例让你可以指定类名称来获得类的相关信息。

package cn.sunzn.demo;

public class ClassDemo {

    public static void main(String[] args) {

        try {
Class c = Class.forName(args[0]);
System.out.println("类名称:" + c.getName());
System.out.println("是否为接口:" + c.isInterface());
System.out.println("是否为基本类型:" + c.isPrimitive());
System.out.println("是否为数组:" + c.isArray());
System.out.println("父类:" + c.getSuperclass().getName());
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("没有指定类名称");
} catch (ClassNotFoundException e) {
System.out.println("找不到指定的类");
}
}
}

在指定类给 forName() 方法后,如果找不到指定的类,会抛出 ClassNotFoundException 异常。Class 的静态 forName() 方法有两个版本,上面的代码是只指定类名称的版本,而另一个版本可以让你指定类名称、加载时是否运行静态区块、指定类加载器:

Static Class forName(String name, boolean initialize, ClassLoader loader)

默认在加载类的时候,如果类中有定义静态区块则会运行它。你可以使用 forName() 的第二个版本,将 initialize 设定为 false,这样在加载类时并不会立即运行静态区块,而会在使用类建立对象时才运行静态区块。为了印证,可以先设计一个测试类。

测试类:TestClass 

package cn.sunzn.demo;

public class TestClass {

    static {
System.out.println("[运行静态区块]");
} }

在测试类 TestClass 中只定义了静态区块显示一段信息,以观察静态区块何时被运行。可以设计范例 ForNameDemo1 使用第一个版本的 forName() 方法。

测试类:ForNameDemo1

package cn.sunzn.demo;

public class ForNameDemo1 {

    public static void main(String[] args) {

        try {
System.out.println("载入 TestClass ");
Class c = Class.forName("cn.sunzn.demo.TestClass"); System.out.println("使用 TestClass 声明参考名称");
TestClass test = null; System.out.println("使用 TestClass 建立对象");
test = new TestClass();
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("没有指定类名称");
} catch (ClassNotFoundException e) {
System.out.println("找不到指定的类");
}
}
}

运行结果如下:

载入 TestClass
[运行静态区块]
使用 TestClass 声明参考名称
使用 TestClass 建立对象

从运行结果中可以看到,第一版本的 forName() 方法在类加载之后,默认会立即运行静态代码块。下面来看范例 ForNameDemo2 中使用第二个版本的 forName() 方法会是如何。


测试类:ForNameDemo2

package cn.sunzn.demo;

public class ForNameDemo2 {

    public static void main(String[] args) {

        try {
System.out.println("载入 TestClass ");
Class c = Class.forName("cn.sunzn.demo.TestClass", false, Thread.currentThread().getContextClassLoader()); System.out.println("使用 TestClass 声明参考名称");
TestClass test = null; System.out.println("使用 TestClass 建立对象");
test = new TestClass();
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("没有指定类名称");
} catch (ClassNotFoundException e) {
System.out.println("找不到指定的类");
}
}
}

运行结果如下:

载入 TestClass
使用 TestClass 声明参考名称
使用 TestClass 建立对象
[运行静态区块]

由于使用第二个版本的 forName() 方法时,设定 initialize 为 false,所以加载类时并不会立即运行静态区块,而会在使用类建立对象时才运行静态区块,第二个版本的 forName() 方法会需要一个类加载器,范例中所使用的是主线程的类加载器。

Java 编程下使用 Class.forName() 加载类的更多相关文章

  1. Java 编程下使用 Class.forName() 加载类【转】

    在一些应用中,无法事先知道使用者将加载什么类,而必须让使用者指定类名称以加载类,可以使用 Class 的静态 forName() 方法实现动态加载类.下面的范例让你可以指定类名称来获得类的相关信息. ...

  2. Java从Jar文件中动态加载类

    动态加载jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行. 下面通过一个实例来直观演示: 第一: ...

  3. Java 编程下简介 Class 与类加载

    即使有一个类并对它一无所知,但其实它本身就包含了许多信息,Java 在需要使用到某个类时才会将类加载,并在 JVM 中以一个 java.lang.Class 的实例存在.从 Calss 实例开始,可以 ...

  4. 反射01 Class类的使用、动态加载类、类类型说明、获取类的信息

    0 Java反射机制 反射(Reflection)是 Java 的高级特性之一,是框架实现的基础. 0.1 定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...

  5. [改善Java代码]使用forName动态加载类文件

    动态加载(Dynamic Loading)是指在程序运行时加载需要的类库文件,对Java程序来说,一般情况下,一个类文件在启动时或首次初始化时会被加载到内存中,而反射则可以在运行时再决定是否需要加载一 ...

  6. java中class.forName和classLoader加载类的区分

     java中class.forName和classLoader都可用来对类进行加载.前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块.而classLoade ...

  7. Java日志组件logback使用:加载非类路径下的配置文件并设置定时更新

    Java日志组件logback使用:加载非类路径下的配置文件并设置定时更新 摘自: https://blog.csdn.net/johnson_moon/article/details/7887449 ...

  8. java加载类的方法1.classloader 2.class.forName()

    java加载类的方法1.classloader 2.class.forName() 加载一个类后,是在方法去创建这个类的元信息class对象,在方法区立刻创建.在方法区创建.

  9. JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了

    JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了 代码示例 转自 https://docs.oracle.com/javase/tutorial/jdbc/o ...

随机推荐

  1. Java基础知识强化47:StringBuffer类之StringBuffer的三个面试题

    1. 面试题:String,StringBuffer,StringBuilder的区别 ? 答:String是字符串内容不可变的,而StringBuffer和StringBuilder是字符串内容长度 ...

  2. Java基础知识强化44:StringBuffer类之把数组拼接成指定格式的字符串的案例

    1. 先看案例代码如下: package cn.itcast_07; /* * 把数组拼接成一个字符串 */ public class StringBufferTest2 { public stati ...

  3. 配置 VS 2015 开发跨平台手机应用

    为了使用 VS 2015 开发跨平台手机应用,VS 2015 装了很多次,遇到了很多坑,才终于弄明白怎样配置才能正常使用C#开发手机应用,现把步骤分享给大家,以免大家少走弯路. 运行环境: Windo ...

  4. WPF采用MVVM模式(绑定:纯前台、命令:触发器绑定命令)

    MVVM绑定 view-viewModel-model,模型介绍省略,就是创建类,添加字段封装属性.注:控件的绑定只能绑定到属性上,不能绑定到字段上: 接下来就是代码 (view): <Wind ...

  5. C++ 完美破解九宫格(数独)游戏

    看到CSDN上有位大神用C#写了一个破解数独的程序(点击打开链接),不过我对C#也不懂,比较喜欢C++,就用标准C++也写了一个,希望各位喜欢.三纯程序,纯控制台程序,纯各人爱好,纯算法程序,无win ...

  6. html Table实现表头固定

    最近一直在搞前台琐碎的东西,也学习了一下linux,没有时间对新的东西进行深入的研究和学习,没有写博客,不过归咎其原因还是在于自己的惰怠. 废话不多说,今天想将一个前台页面设计的一个小东西分享一下,那 ...

  7. LINUX服务器配置NFS服务,挂载外部存储实现目录共享

    安装nfs  rpcbind 一.服务端配置 安装 NFS 服务器所需的软件包:nfs 和 rpcbind # yum install nfs-utils # yum install rpcbind( ...

  8. php 函数strtr 替换函数实例解析 strtr 速度比较快

    先来看看这个php字符串替换函数 PHP字符串替换函数strtr()的两种状态 strtr(string,from,to) 或者strtr(string,array) 首先针对PHP字符串替换函数st ...

  9. Python学习笔记整理(三)Python中的动态类型简介

    Python中只有一个赋值模型 一.缺少类型声明语句的情况 在Python中,类型是在运行过程中自动决定的,而不是通过代码声明.这意味着没有必要事声明变量.只要记住,这个概念实质上对变量,对象和它们之 ...

  10. Spark link集合

    Part1. 各种参数的意义及如何配置 Spark官方文档——Spark Configuration(Spark配置) http://www.cnblogs.com/vincent-hv/p/3316 ...