黑马程序员技术交流社区

标题: 字符串问题 [打印本页]

作者: \(^o^)/    时间: 2014-4-18 22:02
标题: 字符串问题
本帖最后由 \(^o^)/ 于 2014-4-20 16:24 编辑

看视频的时候有个提到了字符串
String s1="abc";
s1是一个类类型的变量,abc是一个对象。

请问s1不是字符串类型的变量吗?怎么成类类型变量去了,老师也没讲。
作者: ノtrack    时间: 2014-4-18 22:19
Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生。

一、从根本上认识java.lang.String类和String池

首先,我建议先看看String类的源码实现,这是从本质上认识String类的根本出发点。从中可以看到:
1、String类是final的,不可被继承。public final class String。
2、String类是的本质是字符数组char[], 并且其值不可改变。private final char value[];
然后打开String类的API文档,可以发现:
3、String类对象有个特殊的创建的方式,就是直接指定比如String x = "abc","abc"就表示一个字符串对象。而x是"abc"对象的地址,也叫做"abc"对象的引用。
4、String对象可以通过“+”串联。串联后会生成新的字符串。也可以通过concat()来串联,这个后面会讲述。
6、Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。下面是个系统内存示意图:


5、创建字符串的方式很多,归纳起来有三类:
其一,使用new关键字创建字符串,比如String s1 = new String("abc");
其二,直接指定。比如String s2 = "abc";
其三,使用串联生成新的字符串。比如String s3 = "ab" + "c";

二、String对象的创建

String对象的创建也很讲究,关键是要明白其原理。
原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。

原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。

原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。

原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。

另外,String的intern()方法是一个本地方法,定义为public native String intern(); intern()方法的价值在于让开发者能将注意力集中到String池上。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
作者: vtming    时间: 2014-4-18 23:22
String 是一个类,不是基本数据类型。你声明了s1为String类型,s1自然是类类型变量,也可以说是引用类型。
String中文名字是 字符串类,所以s1也可以说是 字符串类型变量。
说s1是类类型变量,是为了区别基本数据类型的。

作者: skill20    时间: 2014-4-19 00:37
Java 一共有 8 种基本类型:byte, short, int , long , char , float , double, boolean.
其他的都是引用数据类型:可以通过new 来建立对象。
个人见解。
作者: Royvan    时间: 2014-4-19 09:14
String是一个类。
建议楼主回忆下Java标识符的命名规则,这个必须懂
基本数据类型第一个字母是小写的。

作者: Emperors    时间: 2014-4-19 10:51
字符
   构造方法:
     1、String():空参数构造
     2、String(byte[] byte):使用字节数组成一个字符串
     3、String(byte[] byte,int offset,int length):使用字节数的一部分组成一个字符串
     4、String(char[] value):使用字符数组成一个字符串。
     5、String(char [] value,int offset,int count):使用字节数的一部分组成一个字符串
         6、String(String str):把字符串常量组成字符串对象
         7、第七种是直接赋值使用
          
String类的判断功能
   boolean equals (object obj):比较字符串的内容是否相同,区分大小写
   boolean equalslgnoreCase(String str):比较字符串的内容是否相同,不区分大小写
   boolean contains(String str):判断字符串对象是否包含一个串
   boolean startWith(String str):判断某个字符串是否以指定的内容开头
   boolean endsWith(String str ):判断某个字符串是否以指定的内容结尾
   boolean isEmpty():判断字符串是否为空
          
          
byte[] getBytes():通过字符串得到一个字节数组
char[] tocharArray():通过字符串得到一个字符数组
static String copyValulueOF(char[] chs):把字符数组变成字符串
static String valueof(char[] chs):把字符数组变成字符串
static String valueof(int i):基本类型:把任意类型变成字符串
String toLoweCase() 转成小写
String toUpperCase():转成大写
String concat(String str) :字符串的连续

构造方法:
  Rardom():使用默认种子(当前时间的毫秒值)
  Rardom.(long seed):带种子的

成员方法:
  int nextInt():生成一个int范围内分布均匀的值
  int nextInt(int n ):生成 的是一个[0,n)范围内的值
注意:
        String类是不可变(final)的,对String类的任何改变,都是返回一个新的String类对象.这样的话把String类的引用传递给一个方法,该方法对String的任何改变,对原引用指向的对象没有任何影响,这一点和基本数据类型基本相似.。
  你那个代码还是基本数据类型没完全搞懂,被你模糊了吧   
     建议楼主多查查StringApI,多了解一下它的源代码
    多写几个这个例子,你会有所自己的见解的   这样记得比较清
   另外楼上说的挺好的,你可以多参考参考



作者: peku    时间: 2014-4-19 11:06
因为String不是基本数据类型,而是引用数据类型,引用数据类型就是java本身定义的类,所以从根本上来说,s1是一个类类型变量,就好像我说你是中国人,但也可以说你是人一样,因为中国人同样也是人
作者: 天涯追梦    时间: 2014-4-19 13:01
String不属于8种基本数据类型,String是一个对象。  因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性
String 既可以写成String s1 = "abc",也可以写成String s2 = new String ("abc"),
关于二者的区别请看下面说明:
---------------------------------------------
先说几个概念吧

1.常量池

  指的是在编译期确定,并被保存在已编译的字节码文件中的一些数据,它包括类、方法、接口等中的常量,也包括字符串常量。

2.==: 比较是否是同一个对象

3.equals(): 比较的是对象里的内容

---------------------------------------------
下面我开始说区别

第1种:

  String a="abc";
  String b="abc";
  System.out.print(a==b);
  
  结果:true

  原因:编译时,这两个"abc"被认为是同一个对象保存到了常量池中;运行时JVM则认为这两个变量赋的是同一个对象,所以返回true。

---------------------
第2种:

  String a=new String("abc");
  String b=new String("abc");
  System.out.print(a==b);

  结果:false

  原因:用构造器创建的对象,是不会被放入常理池中的,也很明显这完全是两个对象,只是内容相同罢了,结果当然为false了。用equals()或者System.out.print(a.intern()==b.intern());就返回true了。

------------------------------
第3种

  String a="abc";
  String b=new String("abc");
  System.out.print(a==b);

  结果:false

  原因:同上

---------------------------
第4种

  String a="abcdef";
  System.out.print(a=="abcdef");

  结果:true

  原因:运行出现的字符串常量,若是在常量池中出现过,则JVM会认为同一个对象,以节省内存开销,所以这两个字符串会被认为是同一个对象。

-------------------------------------------
第5种

  String a="abcdef";
  String b="";
  String c=a+b;
  System.out.print(c=="abcdef");

  结果:false

  原因:编译时,先将"abcedf"放在常量池中,而c的值则是在运行时在堆里创建的。所以为false。

---------------------------------------------------------------------
其它太明显的区别不在赘述。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2