`

忆Java String

    博客分类:
  • Java
阅读更多

 

平时 .NET 写多了, Java 很多东西都忘记了,前两天和同事聊天说到 equals 时谈到 Java 中的 String 时自己没能理清楚,唉,以前都研究过了,但还是忘了(头脑不行了),所以决定记在这里给自己长长脑子。

 

Java 时,我们可以发现对于 String 类型的实例化方式有以下两种:

· String str = “abc”;// 通过直接赋值的方式

· String str = new String(“abc”);// 通过构造方法完成

 

那么我们来看看这两种方式 Java 内部是如何处理的呢?

1 、直接赋值方式( String str = “abc” ):

2、通过构造方式(String str = new String(“abc”)):

通过上面的内存关系图可以发现通过构造方法实例化时程序开辟了两个空间,与直接赋值的方式相比,要浪费内存空间,所以可以总结出String实例化优先考虑使用直接赋值的方式。

那么通过上面的String堆栈我们又可以引伸出String的比较方式“==”和“equals”,我们以下面的一个简单的范例来说明问题:

public static void main(String[] args) {
		String str1 = "hello"; // 使用直接赋值的方式完成
		String str2 = new String("hello"); // 通过构造方法完成
		String str3 = str2; // 通过构造方法完成
		System.out.println("str1 == str2 --> " + (str1 == str2)); // false
		System.out.println("str1 == str3 --> " + (str1 == str3)); // false
		System.out.println("str2 == str3 --> " + (str2 == str3)); // true
		System.out.println("str1.equals(str2)-->" + str1.equals(str2));// true
		System.out.println("str1.equals(str3)-->" + str1.equals(str3));// true
		System.out.println("str2.equals(str3)-->" + str2.equals(str3));// true
	}

 分析:对上面程序进行内存划分

 

 

 

说明:

         我们来看看“ == ”与“ equals ”分别指的是什么?

                   ·“ == ”:比较的是两个对象的地址是否相等,具体的来说就是比较地址的值,因地址是以数值的形式存在的;

                   ·“ equals ”:比较的是两个字符串的内容;

 

以下是很早以前从网上找的关于 Java 内存划分的说明

 

1、  寄存器:最快的存储区,由编译器根据需求进行分配,而我们在程序中是无法控的;

 

2 、栈:存放基本类型的变量数据和对象引用,但对象本身不存放在栈中,而是存放在堆中( new 出来的对象)或者常量池中(字符串常量对象存放在常量池中);

栈的说明:

         当在一段代码块定义一个变量时, Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后, Java 会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用;

栈的优缺点:

         栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量( ,int, short, long, byte, float, double, boolean, char )和对象句柄。

范例:关于存在栈中的数据可以共享

假设我们同时定义:

int a = 3;

int b = 3

编译器先处理 int a = 3 ;首先它会在栈中创建一个变量为 a 的引用,然后查找栈中是否有 3 这个值,如果没找到,就将 3 存放进来,然后将 a 指向 3 。接着处理 int b = 3 ;在创建完 b 的引用变量后,因为在栈中已经有 3 这个值,便将 b 直接指向 3 。这样,就出现了 a b 同时均指向 3 的情况。这时,如果再令 a=4 ;那么编译器会重新搜索栈中是否有 4 值,如果没有,则将 4 存放进来,并令 a 指向 4 ;如果已经有了,则直接将 a 指向这个地址。因此 a 值的改变不会影响到 b 的值。要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况 a 的修改并不会影响到 b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。

 

3 、堆:存放所有 new 出来的对象和数组

堆的说明:

         在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量 , 这里引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象;

堆的优缺点:

         Java 的堆是一个运行时数据区 , 类的对象从中分配空间。这些对象通过 new newarray anewarray multianewarray 等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的, Java 的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

 

4 、静态域:存放静态成员( Static 定义的);

 

5 、常量池:存放字符串常量(注:此处本人只能确定肯定有字符串常量,对于其他本人不确定,待定中… . ,网上也有说可以存放基本类型常量 public static final );

常量池的说明:

当然常量池中的对象可以共享,对于堆中的对象不可以共享,还有一点就是对于 equals 相等的字符串,在常量池中永远只有一份,而在堆中是有多份的;

 

6 、非 RAM 存储:硬盘等永久存储空间;

补充:

         栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性

 

	 int i1 = 9;
		 int i2 = 9;
		 int i3 = 9;
		 public static final int INT1 = 9;
		 public static final int INT2 = 9;
		 public static final int INT3 = 9;

 

 

 

package org.lxh.test;
class BirthDate {
	private int day;
	private int month;
	private int year;
	public BirthDate(int d, int m, int y) {
		day = d;
		month = m;
		year = y;
	}
	public int getDay() {
		return day;
	}
	public void setDay(int day) {
		this.day = day;
	}
	public int getMonth() {
		return month;
	}
	public void setMonth(int month) {
		this.month = month;
	}
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
}
public class Test{
	public static void main(String args[]) {
		int date = 9;
		Testtest = new Test ();
		test.change(date);
		BirthDate bd = new BirthDate(7, 8, 98);
		System.out.println(bd.getDay() + "、" + bd.getMonth() + "、"
				+ bd.getYear());
	}
	public void change(int i) {
		i = 1234;
	}
}

 

 

 

1). main方法开始执行:int date = 9;
date局部变量,基础类型,引用和值都存在栈中。
2). Test test = new Test();
test为对象引用,存在栈中,对象(new Test())存在堆中。
3). test.change(date);
i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。
4). BirthDate d1= new BirthDate(7,7,1970);
d1为对象引用,存在栈中,对象(new BirthDate())存在堆中,其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中。day,month,year为成员变量,它们存储在堆中(new BirthDate()里面)。当BirthDate构造方法执行完之后,d,m,y将从栈中消失。
5).main方法执行完之后,date变量,test,d1引用将从栈中消失,new Test(),new BirthDate()将等待垃圾回收。

  • 大小: 8.4 KB
  • 大小: 25.9 KB
  • 大小: 22.5 KB
  • 大小: 17.7 KB
  • 大小: 30.8 KB
分享到:
评论

相关推荐

    计算string类型算式的结果

    `execute.java`可能包含了主函数和调用逻辑,而`string.java`则可能包含了字符串解析和计算的核心功能。这两个文件的交互是通过调用方法和返回值来实现的。 8. **性能优化**:对于大量表达式的计算,我们还可以考虑...

    2020Java学习路线规划.pdf

    Java还提供了丰富的系统类如System、String、Math、Date、Calendar等,学习这些类的使用对于开发各种功能的应用程序是必不可少的。了解JVM(Java虚拟机)的概念对于理解Java代码的运行环境也很重要。 最后,设计...

    java慕课uooc答案

    Java 语言的字符串类型是不可变的,可以通过 String 类来创建字符串对象。Java 语言的字符串可以通过操作符进行连接、比较、 substring 等操作。 Java 语言的字符串可以应用于数据处理、文本处理、网络通信等领域。...

    关于集合的小例子java

    在Java编程语言中,集合框架是处理对象数组的重要工具,提供了高效的数据组织和操作方式。本教程将聚焦于三个特定的集合类:`Vector`、`Stack`和`HashSet`,通过小型示例来深入理解它们的特点和用法。 首先,`...

    JAVA程序的总结和提升

    其固定格式表明了它是静态的,返回类型为void,参数为String类型的数组,这使得我们可以从命令行传递参数给程序。 在Java中,花括号用于定义代码块,如类、方法或循环。虽然编译器忽略空格,但为了代码可读性,应...

    Java jdbc分页工具类

    java jdbc 分页工具类,以及返回集合数据的封装, private int limit = 10;//每页的个数 /** * 当前页 */ private int page; // /** * 总行数 */ private int totalRows; // /** * 总页数 */ private ...

    使用Java理解程序逻辑上机参考代码

    4. **字符串操作**:第六章可能会讲解Java中的String类,包括字符串的创建、拼接、查找、替换和分割等操作。 5. **异常处理**:第七章涉及Java的异常处理机制,包括try-catch-finally语句块,异常的类型和自定义...

    java复习笔记,适用于本科学习

    Java是世界上最流行的编程语言之一,尤其在企业级应用和服务器端开发中占据着主导地位。本文将基于"java复习笔记,适用于本科学习"的主题,深入探讨Java编程中的相关知识点。 首先,我们要了解的是Scanner类,它是...

    Elasticsearch java操作代码

    Map<String, Object> sourceAsMap = getResponse.getSourceAsMap(); // 更新源数据 sourceAsMap.put("message", "updated message"); UpdateRequest updateRequest = new UpdateRequest("my_index", "1").doc...

    java实现“黑客帝国”中的gui

    在Java编程语言中,GUI(图形用户界面)是创建交互式应用程序的重要部分。"黑客帝国"中的GUI通常指的是电影中那种动态的、充满数字流的画面,这种效果在编程中可以通过模拟字符滚动来实现。本教程将详细介绍如何使用...

    Java 工具类 ping Ip 是否通

    通过参数 ip 判断网络是否连接通常,public static boolean getPing(String ip){ // 方法一 最常用的 PING 方法 Runtime runtime = Runtime.getRuntime(); // 获取当前程序的运行进对象 Process process = null; ...

    2021-03java面试题.docx

    Java是世界上最流行的编程语言之一,尤其在企业级应用开发中占据主导地位。了解Java的基础以及其新特性对于Java开发者来说至关重要。以下是一些基于提供的面试题文档内容的关键知识点的详细解释: 1. **数据类型与...

    使用Java与Python十大排序算法之直接插入排序

    public static void main(String[] args) { int[] array = {34, 21, 13, 2, 5, 1, 55, 3, 1, 8}; insertSort(array); System.out.println(Arrays.toString(array)); } public static void insertSort(int[] ...

    javaQQserverSource

    Java的`ByteInputStream`和`ByteOutputStream`可以帮助我们处理二进制数据,而`String`和`Scanner`则用于处理文本数据。 4. **数据库操作**:用户信息、好友关系、聊天记录等都需要持久化存储。Java的JDBC(Java ...

    接口的使用—对okgo进行简单的再封装

    在Java中,接口是类型定义的一个集合,包含了常量和抽象方法。本话题主要围绕如何利用接口来对OkGo进行简单的再封装,以提高代码的可复用性和可维护性。 OkGo是一款高效的Android网络请求库,它基于OkHttp构建,...

    jsch-0.1.54

    String line; while ((line = reader.readLine()) != null) { System.out.println(line); } channel.disconnect(); session.disconnect(); ``` **总结** `jsch-0.1.54.jar` 是一个强大的Java SSH客户端库,它...

    自定义对话框

    public CustomProgressDialog setMessage(String message) { // 设置消息文本... return this; } // 创建并显示对话框 public CustomProgressDialog show() { AlertDialog dialog = create(); dialog.show...

Global site tag (gtag.js) - Google Analytics