文档章节

java:String不是基本类型,不是数组,是类,而数组也是类

樂天
 樂天
发布于 2015/05/17 08:54
字数 1012
阅读 206
收藏 1

环境:jdk 1.7。

本文可以用一句话总结:String不是基本类型,不是数组,是类,而数组也是类。

由于脚本语言使用较多,我在java中也写过这样的代码:

String str = "hi";
System.out.println(str[1]); // 错误的

可惜是错的。str是java.lang.String类的一个对象,无法使用[]运算符。真正可用的代码是这样的:

String str = "hi";
System.out.println(str.charAt(1));

###数组是类


请参考java:反转数组,以及System.out的实现机制

其实,从下面的语句就可以看出来:

int[] ia = new int[9];

也可以从下面的代码片段中看出来:

char[] arr = {'a', 'b', 'c'};
char[] arr2 = arr;         // 引用   
System.out.println(arr);   // abc
System.out.println(arr2);  // abc
arr[1] = '6';
System.out.println(arr);   // a6c
System.out.println(arr2);  // a6c

###String不是基本类型


java提供了8个基本类型,分别是:byte、short、int、long、float、double、boolean和char,并没有String。基本类型可以以下面的形式定义变量并赋值:

int a = 5;

上面的变量a是一个基本类型变量,不是对象,所以变量a没有任何属性和方法,只有

当然,这8个基本类型也有对应的类,分别是java.lang包下的Byte、Short、Integer、Long、Float、Double、Boolean、Character。这8个类都有一个私有的使用基本类型的变量value来保存值。

Java中有“自动装箱”、“自动拆箱”的概念,这是针对基本类型和它们对应的类而言的。

自动装箱:把基本类型用它们对应的引用类型包装起来,使它们具有对象的特质,可以调用toString()、hashCode()、getClass()、equals()等方法。

拆箱:跟自动装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为基本类型的数据。

注意:自动装箱和拆箱是由编译器来完成的,编译器会在编译期根据语法决定是否进行装箱和拆箱动作。

代码示例:

Integer a = 5;          // 自动装箱
int b = new Integer(6); // 自动拆箱
System.out.println(a);  // 5
System.out.println(b);  // 6

###String不是数组


因为无法使用数组运算符[]

###String内部实现


String是一个类,具体是java.lang.String,查看其源码,可以看到

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

char数组value用来存储字符串。注意char类型的下面的性质:

char类型是一个单一的16位Unicode字符;
最小值是’\u0000’(即为0);
最大值是’\uffff’(即为65,535);
char数据类型可以储存任何字符;
例子:char letter = 'A'。

String类并没有暴露可以修改value的方法,所以可以认为String是无法修改的。

下面是一个示例:

char[] arr = {'a', 'b', 'c'};
String str = new String(arr);
System.out.println(arr);  // abc
System.out.println(str);  // abc
arr[1] = '6';
System.out.println(arr);  // a6c
System.out.println(str);  // abc

其中:new String(arr);使用了下面的构造方法:

public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}

这相当于把arr的内容拷贝一份,让后让this.value指向它新生成的数组。所以,在arr[1] = '6';后,字符串对象str的value并没改变。

###那么"123"意味着?


看一下下面的代码:

package hellojava;
    
public class HelloJava {
    
    void hi(char[] arr) {
        System.out.println("hi, char[]");
    }
    
    void hi(String str) {
        System.out.println("hi, String");
    }
    
    public static void main(String[] args) {

        HelloJava hj = new HelloJava();
        char[] arr = {'a', 'b'};
        hj.hi("123");
        // hj.hi({'a', 'b'}); // 错误
        hj.hi(arr);
        
    }
}

运行结果是:

hi, String
hi, char[]

所以"123"是代表着String。

如果上面的代码中,没有void hi(String str)方法,那么hj.hi("123");也会报错。

###补充


String类下还有这个构造方法:

String(char[] value, boolean share) {
    // assert share : "unshared not supported";
    this.value = value;
}

如果该构造方法使用public修饰了,那么,下面的代码是成立的:

// 这段代码在实际中是不成立的
char[] arr = {'a', 'b', 'c'};
String str = new String(arr, true);
System.out.println(arr);  // abc
System.out.println(str);  // abc
arr[1] = '6';
System.out.println(arr);  // a6c
System.out.println(str);  //-> 结果会是: a6c

也就是String能被修改了,然而该构造方法没有使用public修饰。只有同在java.lang包中的类才能使用。

© 著作权归作者所有

樂天
粉丝 138
博文 674
码字总数 147858
作品 3
深圳
程序员
私信 提问
Java--数据类型及类型转换

Java数据类型: 基本数据类型又被称为主类型,并且每个主类型都有相对应的“封装器类型”。 boolean-1位、char-4位、byte-8位、short-16位、int-32位、long-64位、float-32位、double-64位。...

SuperHeroes
2018/01/30
37
0
Android JNI学习(四)——JNI的常用方法的中文API

本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Native相互调用 Android JNI学习(四)——JNI的常用方法...

隔壁老李头
2018/05/09
0
0
asm学习2-java类在asm里的基本描述

上节里有关于asm的一些基本概念,比如:visit里的第一个类版本,方法的描述、引用描述等,下面将一一介绍。 类版本 一个Java二进制的类文件,都有一个版本,对应于不同的jdk版本。因此ASM中提...

messud4312
2015/02/06
284
0
再谈Java数据结构—分析底层实现与应用注意事项

在回顾js数据结构,写《再谈js对象数据结构底层实现原理-object array map set》系列的时候,在来整理下java的数据结构。 java把内存分两种:一种是栈内存,另一种是堆内存 基本类型在栈区分...

zhoulujun
05/17
50
0
你不知道的 equals 和 ==

先来看一道 equals和 == 相关的面试题吧。 先告诉你答案是 true,true,false,true。 i1 == i2 和 i1.equals(i2) 这两个都是 true,大多数人应该可以答对。后面的 i3 == i4 和 i3.equals(i4...

Wizey
2018/08/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

实现线程类的两种方式

一、让目标类继承Thread类 package com.atzhongruan.springboot_boostrap.Test;/** * @Author jose * date 2019 */public class Task1 extends Thread{ @Override pub......

zhengzhixiang
32分钟前
4
0
OSChina 周日乱弹 —— 然而并不能,他是公的。

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @小小编辑推荐:《兔子姑娘》- 陈老实 《兔子姑娘》- 陈老实 手机党少年们想听歌,请使劲儿戳(这里) @曼尼22 :我倒要看看我头发啥时候掉完...

小小编辑
38分钟前
58
5
QML学习之浅谈Window

转载地址:http://blog.csdn.net/kanchuan1905/article/details/53762788 在Qt Quick的世界里,Window对象用于创建一个与操作系统相关的顶层窗口,包含了如Text, Rectangle, Image等元素。W...

shzwork
今天
6
0
centos 查看删除旧内核

1、查看系统中安装的内核 $ yum list installed | grep kernel 2、删除系统中旧内核 $ yum install yum-utils$ package-cleanup --oldkernels --count=2...

编程老陆
今天
10
0
ES6

ES6:不改变原理的基础上,让API变得更简单 一、let:代替var用于声明变量 1、var的缺点: (1)声明提前 (2)没有块级作用域 2、let的优点: (1)组织了申明提前 (2)让let所在的块({}),...

wytao1995
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部