Java Core

一、通过new关键字创建对象

Hello hello = null;  //  声明一个引用

hello = new Hello();  //  创建对象

以上两行代码相当于 Hello hello = new Hello();

这行代码实际上包含了四个动作:

1.new Hello指的是以Hello类为模板在堆中创建一个Hello对象。类实际上就是一个模板。

2.()指的是创建完对象后,调用该类的构造函数,对刚创建好的对象进行初始化。注意,new 是一个关键字。

3.Hello hello  指的是创建一个hello类型的引用,JVM为该引用在栈里分配了空间。

4.  = 操作符表示把引用指向创建好的对象,也就是将对象的地址传给了左边的引用。

注意:很多教程中,将‘=’解释成赋值,而它实际上是一个传地址的过程。引用里存储的并不是对象本身,而是对象的地址。

这种方式的缺点:需要在当前类导入该对象对应的类,提高了代码的耦合度。

创建对象时,引用和对象的关系在JVM内存中关系如下:

参考文献:https://www.cnblogs.com/focusChen/articles/2497768.html

二、通过反射机制创建对象

 在学习反射机制之前先了解Class类。Class类封装了一个对象或者接口运行时的状态,当一个类被装载时,该类的Class类的对象自动创建。它记录了有哪些对象是通过当前类创建。一个Class类只能创建一个对象。

1.Class类也是一个类,它的名字与class关键字很相似,但不是同一个东西。

2.Class类的对象内容是你创建的类的类型信息,比如你创建了一个Apple类,那么JVM会自动创建一个Apple类的Class类的对象。

3.Class类的对象不能用new的方式创建,它只能由JVM创建,因为Class类的构造方法是私有的。

4.Class类的作用是运行时提供或者获得某个对象的类型信息,这些信息可以用于反射。

假设现在有一个Apple类,那么获取Apple类的Class类的对象的方法:

1.用Class类的forName()函数

Class  obj = Class.forName("Apple"); # obj为Apple类的Class类的对象

2.使用对象的getClass()函数

Apple apple = new Apple(); # apple为Apple对象的引用
Class obj = apple.getClass();  # obj为Apple类的Clas类的对象的引用

3.使用类字面量常量

Class obj = Apple.class; # obj为Apple类的Class类的对象的引用

获取到Apple类的Class类的对象有什么用呢?

答:通过Apple类的Class对象可以创建Apple类的一个对象,这种创建对象的方式叫做反射。

 Hello hello = Hello.class.newInstance();  
 Hello hello = (Hello) Class.forName("Hello").newInstance(); 
// 若forName()的参数对应的类不存在则会抛出ClassNotFound的错误

以上两行代码都能通过Hellol类的Class类的对象的newInstance()方法来创建Hello类的对象。

有网友说,调用newInstanc()方法的前提是Hello类中必须有无参构造方法,否则会抛出java.lang.InstaniationException的错误,

对此我表示怀疑,因为在编码者没有在类中编写无参构造函数时,JVM也会自动生成一个无参构造函数。随后并删掉了Hello类的

无参函数,重新执行,没有抛出错误。第二次验证:我的怀疑是正确的。

 

通过new关键字和newInstance()分别创建对象的区别是:

前者在创建对象时,类可以是没有被加载的情况,而在调用newInstance()方法前,该类必须已经被加载。

当然我们还需要理解Class.forName()函数:

该函数返回的是一个类的Class类的对象,它的作用是要求JVM查找并加载指定的类,在加载过程中会执行该类的静态代码块。

关于类的加载原理参考:https://cloud.tencent.com/developer/article/1018594

newInstance()是实现IOC、反射、面对接口编程 和 依赖倒置 等技术方法的必然选择,new 只能实现具体类的实例化,不适合于接口编程。

 

 

原文地址:https://www.cnblogs.com/2sheep2simple/p/10682868.html