首页 > 其他分享 >关于Class.forName(className).newInstance()介绍

关于Class.forName(className).newInstance()介绍

时间:2023-05-05 18:01:24浏览次数:54  
标签:装载 forName 初始化 newInstance className Class 加载

Class.forName(xxx.xx.xx) 返回的是一个类

首先你要明白在java里面任何class都要装载在虚拟机上才能运行。这句话就是装载类用的(和new 不一样,要分清楚)。 

至于什么时候用,你可以考虑一下这个问题,给你一个字符串变量,它代表一个类的包名和类名,你怎么实例化它?只有你提到的这个方法了,不过要再加一点。 
A a = (A)Class.forName("pacage.A").newInstance(); 
这和你 
A a = new A(); 
是一样的效果。 

关于补充的问题 
答案是肯定的,jvm会执行静态代码段,你要记住一个概念,静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了。而且以后不会再走这段静态代码了。

Class.forName(xxx.xx.xx) 返回的是一个类 
Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段

动态加载和创建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就可以。 

从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用newInstance()方法的时候,就必须保证:1、这个 类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 java API的那个加载器。 

现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。 

最后用最简单的描述来区分new关键字和newInstance()方法的区别: 
newInstance: 弱类型。低效率。只能调用无参构造。 
new: 强类型。相对高效。能调用任何public构造。

介绍的是 forName() 和 ClassLoader 的 loadClass 方法。
现在终于知道了为什么 forName()是会执行 static 语句,因为默认情况它总是初始化这个被装载的类。

关于forName()方法
这个方法总是返回要加载的类的Class类的实例
1、forName(String className)单参数时, initialize=true
    a.总是使用当前类装载器(也就是装载执行forName()请求的类  的类装载器)
    b.总是初始化这个被装载的类(当然也包括:装载、连接、初始化)
2、forName(String className, boolean initialize, ClassLoader loader)
    a.loader指定装载参数类所用的类装载器,如果null则用bootstrp装载器。
    b.initialize=true时,肯定连接,而且初始化了;
    c.false时,绝对不会初始化,但是可能被连接了,但是这里有个例外,如果在调用这个forName()前,已经被初始化了,那么返回的类型也肯定是被初始化的(当然,这里也暗含着:被同一个loader所装载的,而且这个类被初始化了)

关于用户自定义的类装载器的loadClass()方法
1、loadClass(String name)单参数时, resolve=false
    a.如果这个类已经被这个类装载器所装载,那么,返回这个已经被装载的类型的Class的实例,否则,就用这个自定义的类装载器来装载这个class,这时不知道是否被连接。绝对不会被初始化
    b.这时唯一可以保证的是,这个类被装载了。但是不知道这个类是不是被连接和初始化了
2、loadClass(String name, boolean resolve)
    a.resolve=true时,则保证已经装载,而且已经连接了。resolve=falses时,则仅仅是去装载这个类,不关心是否连接了,所以此时可能被连接了,也可能没有被连接

newInstance()有什么用 "newInstance()"是Java中的一个方法,可以用于动态地创建一个类的新实例(对象)。它在反射中使用,反射是Java语言的一项特性,可以在运行时检查、访问和修改类的属性、方法和构造函数等信息。

newInstance()方法可以通过调用类的无参构造函数来创建对象。如果类没有无参构造函数,newInstance()方法会抛出InstantiationException异常。例如,假设有一个名为MyClass的类,可以使用以下代码动态创建一个MyClass对象:

    MyClass myObject =MyClass.class.newInstance();

这个方法
————————————————
原文链接:https://blog.csdn.net/Yhappy727/article/details/102947638

标签:装载,forName,初始化,newInstance,className,Class,加载
From: https://www.cnblogs.com/wbbh/p/17374980.html

相关文章

  • jquery validate 例子延伸--如何使用classname而不是name来验证
    可用例子一:底下内容摘自链接:http://jsfiddle.net/Nbcj9/ 可用例子二:底下内容摘自:http://jsfiddle.net/rq5ra/1/<formid="myform"><inputtype="text"name="field_1"class="num"/><br/><inputtype="te......
  • Class.forName和ClassLoader.loadClass
    一直都忘记他们的区别,在此坐下记录Class.forName("xx.xx")等同于 Class.forName("xx.xx",true,ClassLoader.getSystemClassLoader());//此时已经初始化实例对象了 而ClassLoaderloader=ClassLoader.getSystemClassLoader(); ClassclassName=loader.loadClass("xx.xx");//此......
  • taro3 报错 TypeError: className.split is not a function
    项目原来跑的好好的,昨天升级了几个包,引用了个UI库,然后今天上班运行项目就跑不起来了,项目是在旧的项目上升级的之前的写法<Viewkey={idx}className={["tabbar-item",isActive&&"active"]}onClick={this.switchTab.bind(this,item.key)}>{......
  • js dom className classList
    classListdom.classList.contains('black')//删除blackdom.classList.remove('black')//新增.reddom.classList.add('red')classNameletcName=elementNodeReference.className;elementNodeReference.className=cName;详情见官网......
  • element table 动态设置表头className
    在el-table上添加:header-cell-class-name="HeaderCellClassName"HeaderCellClassName({row,column,rowIndex,columnIndex}){if(columnIndex=......
  • Java中Class.forName和 ClassLoader.loadClass()区别
    一、类加载过程装载:通过累的全限定名获取二进制字节流,将二进制字节流转换成方法区中的运行时数据结构,在内存中生成Java.lang.class对象;  链接:执行下面的校验、准备和解......
  • ClassNames库详解
    简述ClassNames是一个用于有条件处理classname字符串连接的库,非常好用~。简单来说就是动态地去操作类名,把符合条件的类名粘在一起。安装(使用npm)npminstallcl......
  • dataSource or dataSourceClassName or jdbcUrl is required
    前言准备连接双数据库,先测试单独连接,报错java.lang.IllegalArgumentException:dataSourceordataSourceClassNameorjdbcUrlisrequired.原因yml的语法关键字有问题解决......
  • className是覆盖class属性, //classList 是添加属性或者删除已有属性
    className是覆盖class属性,//classList是添加属性或者删除已有属性uul.className="uhh2";还可以对其添加多个选择器,比如uul.className="uhh2changing"(中间用空格隔......
  • 油猴脚本-指定classname和id去除广告
    //==UserScript==//@name广告去除//@namespacehttp://tampermonkey.net///@version0.6//@description移除广告//@authorYou//@m......