Java数据类型:字符串和数组

时间:2009-08-06 20:09:26

标签: java arrays string

我一直在阅读Sun Microsystem的Java教程,并在阅读以下内容时遇到了一些问题:

I/O from the Command Line: The Console Object

"Second, readPassword returns a character array, not a String, so the password can be
 overwritten, removing it from memory as soon as it is no longer needed."

我的问题是:

1)关于其他数据类型,例如值数据类型(int,float,boolean等)和引用类型(用户定义的对象等),Java中的数组和字符串有何不同?

2)你能详细说明关于字符数组和字符串的上述陈述吗?

P.S:

对第一季的澄清:我想在Q1上问的更多关于数组和字符串作为Java中的数据类型的问题......由于它们具有类似对象的属性,当有人声称字符串和数组是不是严格意义上的对象......

3 个答案:

答案 0 :(得分:4)

String在内部将其内容存储为chars的数组。

密码位于Strings的原因是您可以立即在内存中覆盖它。如果它在char[]中,你将不得不等待下一次垃圾收集,你永远不知道它会持续多久;在此之前,攻击者可能会将其从内存中读出来。

答案 1 :(得分:4)

在实际层面上,Stringchar[]之间的主要区别在于前者的实例是不可变的,后者的实例是可变的。当然,String API提供了各种有用的方法字符串操作方法。

让我们来谈谈语言上的相同点和不同点。

首先,(尽管您可能已经听过)Java 中的字符串和数组实例都是对象。根据Java语言规范:

  

4.3.1对象对象是类实例或数组。

     

参考值(通常只是   引用)是指向这些的指针   对象和特殊的空引用,   这指的是没有对象。

...字符串的类是java.lang.String

数组和其他对象类型之间的语言区别是数组的类型不是普通的Java类。例如:

  • 使用与普通类不同的语法声明数组类型。
  • 使用与普通类实例不同的语法创建数组实例。
  • 无法在Java源代码级别命名数组类型。
  • 您不能声明数组类型的子类型/子类。

但是所有数组类型都是java.lang.Object的(直接)子类型,这意味着您可以(例如)将数组分配给类型为Object的变量,并调用Object API中的方法。 (你可以用这些方法做一些有趣的事情来演示数组的“对象”......但我离题了)

那么弦乐呢?如上所述,“字符串”是普通对象,它是类java.lang.String的一个实例。从语言学的角度来看,这门课程并不罕见。它被声明为“最终”,因此您无法声明子类型,但这并不罕见。

与其他类相比,使String有点特殊的是Java语言提供了一些语言结构来支持字符串:

  • 有一种特殊的String字面语法,用于获取其内容可在编译时确定的字符串。
  • “+”运算符已重载以支持String连接。
  • 从Java 7开始,switch语句支持切换String值。
  • Java语言规范定义/假设java.lang.String类具有某些属性和方法;例如字符串是可变的,有一个concat方法,字符串文字是“实习”。

顺便说一下,所有字符串实例都保存在字符串池中的答案是不正确的。字符串仅在它们实现时放入池中,这仅对字符串文字和可在编译时计算其值的字符串自动发生。 (您可以通过调用String.intern()方法强制执行字符串实例,但这有点贵,通常不是一个好主意。)

答案 2 :(得分:1)

正如其他人所说,String是不可变的,所以你不能自己擦除它。即使在收集垃圾之后,内存仍可能完好无损。因此,所有安全协议都将敏感数据定义为字节数组,以便您可以执行此操作,

  char[] password = "secret";

  // After using it
  for (int i; i < password.length; i++) 
     password[i] = 0;
  password = null;