类变量就是static变量;初始值指的是类变量类型的默认值而不是实际要赋的值
(3)解析:jvm将常量池内的符号引用转换为直接引用
行类变量赋值和静态代码块
二、Class.forName()和classloader.loadclass区别
其实该方法内部调用的是:Classloder. loadClass(name, false)
方法:Classloder. loadClass(String name, boolean resolve)
(1)参数name代表类的全限定类名
(2)参数resolve代表是否解析,resolve为true是解析该类
其实该方法内部调用的是:Class.forName(className, true, ClassLoader.getClassLoader(caller))
方法:Class.forName0(String name, boolean initialize, ClassLoader loader)
参数name代表全限定类名
参数initialize表示是否初始化该类,为true是初始化该类
参数loader 对应的类加载器
Class.forName得到的class是已经初始化完成的;
Classloder.loaderClass得到的class是还没有链接的;
三、怎么使用
有些情况是只需要知道这个类的存在而不需要初始化的情况使用Classloder.loaderClass,而有些时候又必须执行初始化就选择Class.forName
例如:数据库驱动加载就是使用Class.froName(“com.mysql.jdbc.Driver”),
下面我们来看看Driver的源代码:
public class Driver extends NonRegisteringDriver implements java.sql.Driver { public Driver() throws SQLException { } <br> static { try { DriverManager.registerDriver( new Driver()); } catch (SQLException var1) { throw new RuntimeException( "Can\'t register driver!" ); } } }
从Driver的源码中我们可以看出Driver这个类只有一个static块,这样我们需要初始化后才能得到DriverManager,所以我们选择使用Class.forName()。
四、class.forName主要功能
Class.forName(xxx.xx.xx)返回的是一个类 Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类, 也就是说JVM会执行该类的静态代码段
五、通过解答以下三个问题的来详细讲解下Class.forName()的用法。
先来个热身,给你一个字符串变量,它代表一个类的包名和类名,你怎么实例化它?你第一想到的肯定是new,但是注意一点:
A a = (A)Class.forName(“pacage.A”).newInstance();
这和你 A a = new A(); 是一样的效果。现在言归正传。
动态加载和创建Class 对象,比如想根据用户输入的字符串来创建对象时需要用到:
String str = “用户输入的字符串” ; Class t = Class.forName(str); t.newInstance();
在初始化一个类,生成一个实例的时候,newInstance()方法和new关键字除了一个是方法,一个是关键字外,最主要有什么区别?它们的区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类。那么为什么会有两种创建对象方式?这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。
Java中工厂模式经常使用newInstance()方法来创建对象,因此从为什么要使用工厂模式上可以找到具体答案。 例如:
class c = Class.forName(“Example”); factory = (ExampleInterface)c.newInstance();
其中ExampleInterface是Example的接口,可以写成如下形式:
String className = “Example”; class c = Class.forName(className); factory = (ExampleInterface)c.newInstance();
进一步可以写成如下形式:
String className = readfromXMlConfig;//从xml 配置文件中获得字符串 class c = Class.forName(className); factory = (ExampleInterface)c.newInstance();
上面代码已经不存在Example的类名称,它的优点是,无论Example类怎么变化,上述代码不变,甚至可以更换Example的兄弟类Example2 , Example3 , Example4……,只要他们继承ExampleInterface就可以。
1、热门面试题及答案大全
面试前做足功夫,让你面试成功率提升一截,这里一份热门350道一线互联网常问面试题及答案助你拿offer
面试宝典+书籍+核心知识获取:戳这里免费下载!诚意满满!!!
2、多线程、高并发、缓存入门到实战项目pdf书籍
3、文中提到面试题答案整理
4、Java核心知识面试宝典
覆盖了JVM 、JAVA集合、JAVA多线程并发、JAVA基础、Spring原理、微服务、Netty与RPC、网络、日志、Zookeeper、Kafka、RabbitMQ、Hbase、MongoDB 、Cassandra、设计模式、负载均衡、数据库、一致性算法 、JAVA算法、数据结构、算法、分布式缓存、Hadoop、Spark、Storm的大量技术点且讲解的非常深入