Java new运算符解析
1、创建数组时,不使用new操作符
Person [] a;
a[0]=new Person(); //Error:variable a might not have been initialized
2、创建对象时,不使用new操作符
Person pe=Person();
pe.talk(); //Error: cannot find symbol
// symbol: method Person()
// location: class test.DataAbstract Person pe;
pe.talk(); //Error: variable pe might not have been initialized
我一直有个困惑,书上说对象的创建3个部分,包括类的加载、对象内存的分配和变量的初始化。官方文档上关于new具体做了什么是这样描述的:
The new operator instantiates a class by allocating memory for a new object and returning a reference to that memory.The new operator also invokes the object constructor.
可以肯定的是,“new Person()”返回的是实例对象的内存空间首地址,可以打印出来的。new作为一个优先级很高的运算符,它的结合性是从右到左,这里它操作的是Person类的构造方法。
好,让我们回到构造方法的定义。
“构造方法是一类特殊的方法,它的名字必须与类名完全相同,且不返回任何数据类型,不能有任何非访问性质的修饰符,也不能用void修饰。”
“构造方法通过new操作符创建对象时被调用。”
书上还说,用一下代码,可以“先创建对象,后初始化对象”:
Person pe;
pe=new Person();
所以到底是谁他妈创建了对象?pe不就是一个Person类型的引用变量吗,最终存储的也只是对象的内存地址啊。
查了很久的资料,可以肯定了,构造方法不返回任何东西!不返回类的实例!不返回类的实例!!它的主要工作是初始化已经创建的实例(应该还为实例的创建提供了类的类型)。
以下是选的部分回答:(StackOverflow)
"The Suns' Java tutorial stands that "The new operator is followed by a call to a constructor, which initializes the new object."Initialize does not mean create.“
The AllocObject function documentation stands that "Allocates a new Java object without invoking any of the constructors for the object. Returns a reference to the object." So in JVM object is not allocated by constructor, but only initialized by it. Looking in constructors' bytecode we are seeing that no object is returned (exactly like in void methods).
所以new操作符才是大哥,new操作符的操作数必须是Constructor,new负责动态分配内存,调用Constructor(并把参数传给它进行初始化),最后返回初始化后的instance的内存空间的首地址。
构造器本质上是个"nonstatic method with name <init> and void return type",只不过这个函数已经不是java语言的一部分了。
在另一个回答中,有人对用new创建类实例对象的的机器码(StackOverflow)。
总结起来就是:new动态分配内存(应该根据类型),调用Constructor,Constructor进行初始化,返回内存首地址。
至于调用操作和返回操作到底应不应该算在new头上(或者JVM?),已经不重要了。重要的是,构造器没有返回任何东西,只是初始化了已经创建的实例。
最后贴一个来自bd知道的回答:
例:Date date1 = new Date();
1. 执行这段代码,虚拟机先查找Date.class文件是否已加载,如果已加载直接跳转到第3步,如果没有则从classPath和相对路径等查找,查找方式由classLoader决定。
2. 找到Date.class文件,虚拟机将Date.class文件加载到内存,解析出class类和注解等元信息,虚拟机保证每个Date.class文件只加载一次。
3. 在堆中申请内存空间存放Date的实例同时进行变量的初始化(类的不同实例只有变量部分不同,方法共享同一份内存),调用无参构造方法Date()进行初始化。
4. 在栈中申请内存空间存放date1句柄变量,将初始化后的实例句柄赋予date1变量。
Java new运算符解析的更多相关文章
- Java 面试知识点解析(四)——版本特性篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
- java jar包解析:打包文件,引入文件
java jar包解析:打包文件,引入文件 cmd下: jar命令:package包打包 javac命令:普通类文件打包 Hello.java: package org.lxh.demo; publi ...
- Java构造和解析Json数据的两种方法详解二
在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Jso ...
- java集合框架之java HashMap代码解析
java集合框架之java HashMap代码解析 文章Java集合框架综述后,具体集合类的代码,首先以既熟悉又陌生的HashMap开始. 源自http://www.codeceo.com/arti ...
- Java注解全面解析(转)
1.基本语法 注解定义看起来很像接口的定义.事实上,与其他任何接口一样,注解也将会编译成class文件. @Target(ElementType.Method) @Retention(Retentio ...
- java移位运算符具体解释
java移位运算符不外乎就这三种:<<(左移).>>(带符号右移)和>>>(无符号右移). 1. 左移运算符 左移运算符<<使指定值的全部位都左移 ...
- 单例模式——Java EE设计模式解析与应用
单例模式 目录: 一.何为单例 二.使用Java EE实现单例模式 三.使用场景 一.何为单例 确保一个类只有一个实例,并且提供了实例的一个全局访问点 1.1 单例模式类图 ...
- Java XML Dom解析工具
Java XML Dom解析工具 缩进等 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); ...
- Java 面试知识点解析(二)——高并发编程篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
随机推荐
- $\LaTeX$数学公式大全13
$13\ Text\ Mode:\ Accents\ and\ Symbols$ $\AA$ \AA $\S$ \S
- Unity常用API备忘录
UnityEditor 复制文本到剪切板 GUIUtility.systemCopyBuffer 获取资源路径 AssetDatabase.GetAssetPath 选择节点 Selection.a ...
- mybatis oracle mysql 批量插入时的坑爹问题--需谨记
mybatis oracle mysql 批量插入一.oracle的批量插入方式insert into db(id, zgbh, shbzh) select '1', '2', '3' from du ...
- Java工程师成神之路(2018年最新版)
一.基础篇 JVM JVM内存结构 堆.栈.方法区.直接内存.堆和栈区别 Java内存模型 内存可见性.重排序.顺序一致性.volatile.锁.final 垃圾回收 内存分配策略.垃圾收集器(G1) ...
- RESTful API是什么?
1. REST 是Repersentational State Transfer的缩写 翻译为"表述性状态传递",那么什么是表述性状态传递呢?为了理解这个词语,我们从"R ...
- bedtools 用法大全
原文:https://cloud.tencent.com/developer/article/1078324 前言: bedtools等工具号称是可以代替普通的生物信息学数据处理工程师的!我这里用一个 ...
- Python 之目录处理
目录处理 OS目录处理目录-->路径,文件夹 文件:txt 1. 新建和删除一个目录 import os #引入os目录from xx import xx os.mkdir("D:\\ ...
- vscode 占内存的方法
1.修复vs code 造成 rg.exe内存占用过大的问题 search.followSymlinks: false 2.修复vs code 造成 git.exe内存占用过大的问题 git.enab ...
- @Transient的应用
我今天分配的任务是为一个页面Debug,遇到了一个问题查询的实体类在数据库没有对应的表,这时最常用的是建立视图或者表,但是应用@Transient注释可以让你更简单,免除建立表还有视图需要找多表关联关 ...
- 例子 使用sqlite3 数据库建立数据方式
#!/usr/bin/env python#coding:utf-8import sqlite3#建立一个数据库cx = sqlite3.connect("E:/test.db") ...