成员变量与局部变量:成员变量可以不赋初值直接使用,打印出默认值;局部变量不赋初值使用出错
保存到什么位置?(此片段摘自java编程思想 第四版)
程序运行时,我们最好对数据保存到什么地方做到心中有数。特别要注意的是内存的分配。有六个地方都可
以保存数据:
(1) 寄存器。这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部。然而,寄存
器的数量十分有限,所以寄存器是根据需要由编译器分配。我们对此没有直接的控制权,也不可能在自己的
程序里找到寄存器存在的任何踪迹。
(2) 堆栈。驻留于常规 RAM(随机访问存储器)区域,但可通过它的“堆栈指针”获得处理的直接支持。堆
栈指针若向下移,会创建新的内存;若向上移,则会释放那些内存。这是一种特别快、特别有效的数据保存
方式,仅次于寄存器。创建程序时,Java 编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存
在时间”。这是由于它必须生成相应的代码,以便向上和向下移动指针。这一限制无疑影响了程序的灵活
性,所以尽管有些Java 数据要保存在堆栈里——特别是对象句柄,但Java 对象并不放到其中。
(3) 堆。一种常规用途的内存池(也在 RAM区域),其中保存了Java 对象。和堆栈不同,“内存堆”或
“堆”(Heap)最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要
在堆里停留多长的时间。因此,用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new命
令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存。当然,为达到这种灵活性,必然
会付出一定的代价:在堆里分配存储空间时会花掉更长的时间!
(4) 静态存储。这儿的“静态”(Static)是指“位于固定位置”(尽管也在RAM里)。程序运行期间,静
态存储的数据将随时等候调用。可用static 关键字指出一个对象的特定元素是静态的。但 Java 对象本身永
远都不会置入静态存储空间。
(5) 常数存储。常数值通常直接置于程序代码内部。这样做是安全的,因为它们永远都不会改变。有的常数
需要严格地保护,所以可考虑将它们置入只读存储器(ROM)。
(6) 非RAM 存储。若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之外。
其中两个最主要的例子便是“流式对象”和“固定对象”。对于流式对象,对象会变成字节流,通常会发给
另一台机器。而对于固定对象,对象保存在磁盘中。即使程序中止运行,它们仍可保持自己的状态不变。对
于这些类型的数据存储,一个特别有用的技巧就是它们能存在于其他媒体中。一旦需要,甚至能将它们恢复
成普通的、基于RAM的对象。Java 1.1 提供了对Lightweight persistence 的支持。未来的版本甚至可能提
供更完整的方案。
Java内存中的栈:
基本类型变量数据(byte short int long char float double boolean)分配一块空间,放在栈中;引用变量也放在栈中。定义一个变量
:
int i; //基本类型变量放在栈中
i = 3; // 局部变量的值也放在栈中
String s; //引用型变量放在栈中
s = new String("hello world"); //此时,涉及到堆。new出来的东西放在堆中
String 创建两种方式分析:
String s1 = "hello world";
String s2 = new String ("hello world");
第一种方式首先在栈中创建一个变量 s1,然后通过引用去字符串常量池中查找是否有"hello world "字符串,如果没有则将"hello world "字符串存入字符串常量池,并使 s1 指向此常量。如果有此字符串则直接指向。
第二种方式是用new来新建对象,存放在堆中,每次调用都会新建一个对象。
String中相等的比较详解 “==”和"equals"
“==”是比较两个对象指向的内存地址是否相等;
"equals"是比较两个对象的值是否相等。
下面以例子逐一说明:
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
编译器首先处理str1时,根据先前所说,在栈中创建一个值为str1的引用,然后查找字符串常量中是否有“abc”这个常量;当执行str2时,由于常量池中已有“abc”字符串,所以将str2直接指向字符串常量“abc”,这样,str1和str2就是指向同一个对象。
String str1 =new String ("hello");
String str2 =new String ("hello");
String str3 = hello //false
System.out.println(str1==str2); // false
new出来的东西都要在堆中新开辟一个空间。str1 先在栈中建一个变量str1,再在堆中new一个hello;str2也是如此,不过在栈中是另一个变量,在堆中又开辟一个新的空间。这样str1和str2指向的就不是同一个对象了。而str3是在常量池中的,当然和堆中的也不相等。
(下图出自csdn论坛)
接下来我们看一下字符串连接的相等问题:
String s0="kvill";
String s1="kv" + "ill";
System.out.println( s0==s1 );//true
仍然是字符串常量,s1在编译器就被确定了,他也是常量池“kvill”中的一个引用。
String s0="kvill";
String s1=new String("kvill");
String s2="kv" + new String("ill");
System.out.println( s0==s1 );//false
System.out.println( s0==s2 );//false
System.out.println( s1==s2 );//false
s0仍然是常量池中的引用;s1无法在编译器确定,所以是运行时在堆中创建的对象“kvill”的引用;s2因为有后半部分,所以也无法在编译期确定,所以也是一个新创建对象“kvill”的引用。
String str1 = "java";
String str2 = "blog";
String s = str1+str2;
System.out.print(s=="javablog");//false……
JVM确实会对型如String str1 = "java"; 的String对象放在字符串常量池里,但是它是在编译时刻那么做的,而String s = str1+str2; 是在运行时刻才能知道(我们当然一眼就看穿了,可是Java必须在运行时才知道的,人脑和电脑的结构不同),也就是说str1+str2是在堆里创建的, s引用当然不可能指向字符串常量池里的对象。
(以下是51CTO的一些片段)
String a = "ab";
String bb = "b";
String b = "a" + bb;
System.out.println((a == b)); //result = false
分析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + bb无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。
分享到:
相关推荐
### Java李兴华学习笔记之Java常用类库 #### 一、课程介绍及知识点概览 根据提供的资料,“Java李兴华学习笔记之Java常用类库”这份文档来源于北京MLDN软件实训中心的教学资料,主要涵盖了Java编程语言中常用类库...
031317_〖第13章:Java类集〗_范例讲解:一对多关系笔记.pdf 031318_〖第13章:Java类集〗_范例讲解:多对多关系笔记.pdf 031401_【第14章:枚举】_枚举的作用笔记.pdf 031402_【第14章:枚举】_Enum笔记.pdf 031403...
Java 8是Java语言发展的一个重要里程碑,引入了许多创新性的特性和改进,...黑马程序员的Java8新特性详解笔记和源码提供了深入学习这些概念的资源,结合实际的代码示例,将有助于你更好地理解和掌握Java 8的核心特性。
### Java学习笔记知识点详解 #### 一、Java环境配置与基本概念 - **系统变量path**: 在设置Java开发环境时,需要配置系统变量`path`,这样计算机才能找到执行Java命令所需的程序。例如,当我们输入`javac`或`java`...
Java的内存管理机制是其强大特性之一,尤其体现在其自动垃圾收集功能上。在Java中,内存主要分为两大块:栈(stack)和堆(heap)。栈内存主要用于存储基本类型的数据和对象的引用,而堆内存则是用于存储所有对象的...
### Java学习笔记精简版详解 #### Java的起源与第一个程序 Java由Sun Microsystems公司于1994年左右为了开发家电系统中的程序而发明,最初名为Oak,后改名为Java。Java的设计初衷是为了克服C语言在嵌入式系统开发...
### JAVA培训笔记知识点详解 #### 一、Java基础知识概述 **1.1 Java程序结构** - **源程序组成**: 在一个Java源程序中可以包含多个Java类。 - **公共类限制**: 只能有一个`public`的Java类,并且源文件名必须与该...
### Java学习笔记知识点详解 #### 一、Java面向对象编程思想 面向对象编程(Object-Oriented Programming, OOP)是Java的核心特性之一。通过封装、继承和多态这三个基本特征来实现。OOP能够提高代码的复用性和可...
10. **泛型**:泛型是Java SE 5引入的新特性,用于增强类型安全,减少类型转换的麻烦,笔记会详解泛型类、泛型方法和通配符等。 11. **JavaFX和Swing**:作为GUI编程的工具,JavaFX和Swing可以创建桌面应用程序,...
`java.lang`是Java的基础包之一,包含了构成Java语言核心API的基本类,如`String`、`Object`、`Integer`等,以及异常类和其他常用类。这部分内容主要涉及: - **基本类型包装类**:如`Integer`、`Double`等,它们...
11. **Java内存管理**:解析Java内存模型,包括堆内存、栈内存、方法区和垃圾回收机制。 12. **设计模式**:讲解常用的23种设计模式,如单例、工厂、装饰器、代理、观察者等,以及它们在实际开发中的应用。 13. **...
- **泛型**:一种可以编写类型安全的代码,同时保持代码复用性的机制。 #### 三、Java语言特性详解 ##### 知识点1:创建和操纵对象 - **创建对象**:`new 类型(参数列表)`。此语句创建了一个指定类型的对象实例。...
【Java核心知识详解】 Java是一种广泛使用的面向对象的编程语言,其基础知识构成了"Core Java"的学习内容。在学习Java时,遵循"多花时间、多动手、多问题"的原则至关重要,因为理论理解与实践操作相结合能更好地...
### Java入门笔记9_Socket详解 #### 一、引言 在计算机网络中,客户端/服务器(Client/Server)模式是常见的通信方式之一。在这种模式下,客户端向服务器发送请求,服务器响应请求并返回数据。Java作为一种广泛使用...
### Java+JDK+6 学习笔记知识点详解 #### 一、Java 概述 - **起源与发展:** - Java 最初是由 Sun Microsystems 的 Green Project 开发出来的编程语言,最初是为了创建一个名为 Star7 的应用程序。 - 1995 年 5 ...
#### 九、数据类型详解 - **整型**: - `byte`:8位,范围-128至127。 - `short`:16位。 - `int`:32位,默认类型。 - `long`:64位,尾部需加`L`或`l`。 #### 十、进制表示法 - **八进制**:前缀`0`,如`int ...
### Java核心API知识点详解 #### 一、集合框架 **1.1 什么是集合** 集合是Java编程语言中用于存储和操作多个元素的一种容器。它提供了动态管理元素的能力,允许在运行时添加或删除元素。 **1.2 集合与数组** - ...