关于String类型的几点说明

1.String是一个特殊的包装类数据。即可以用String str = new String('abc');的形式来创建,也可以用Stringstr = 'abc';的形式来创建(作为对比,在JDK 5.0之前,你从未见过Integer i =3;的表达式,因为类与字面值是不能通用的,除了String。而在JDK 5.0中,这种表达式是可以的!因为编译器在后台进行Integer i= newInteger(3)的转换)。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。Java中的有些类,如DateFormat类,可以通过该类的getInstance()方法来返回一个新创建的类,似乎违反了此原则。其实不然。该类运用了单例模式来返回类的实例,只不过这个实例是在该类内部通过new()来创建的,而getInstance()向外部隐藏了此细节。那为什么在Stringstr = 'abc';中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有。

2. 关于String str = 'abc'的内部工作。Java内部将此语句转化为以下几个步骤:
(1)先定义一个名为str的对String类的对象引用变量:String str;
(2)在栈中查找有没有存放值为'abc'的地址,如果没有,则开辟一个存放字面值为'abc'的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为'abc'的地址,则查找对象o,并返回o的地址。
(3)将str指向对象o的地址。
值得注意的是,一般String类中字符串值都是直接存值的。但像String str = 'abc';这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!

为了更好地说明这个问题,我们可以通过以下的几个代码进行验证。

String str1 = 'abc';
String str2 = 'abc';
System.out.println(str1==str2); //true

注意,我们这里并不用str1.equals(str2);的方式,因为这将比较两个字符串的值是否相等。==号,根据JDK的说明,只有在两个引用都指向了同一个对象时才返回真值。而我们在这里要看的是,str1与str2是否都指向了同一个对象。
结果说明,JVM创建了两个引用str1和str2,但只创建了一个对象,而且两个引用都指向了这个对象。

我们再来更进一步,将以上代码改成:

String str1 = 'abc';
String str2 = 'abc';
str1 = 'bcd';
System.out.println(str1 + ',' + str2); //bcd, abc
System.out.println(str1==str2); //false

这就是说,赋值的变化导致了类对象引用的变化,str1指向了另外一个新对象!而str2仍旧指向原来的对象。上例中,当我们将str1的值改为'bcd'时,JVM发现在栈中没有存放该值的地址,便开辟了这个地址,并创建了一个新的对象,其字符串的值指向这个地址。
事实上,String类被设计成为不可改变(immutable)的类。如果你要改变其值,可以,但JVM在运行时根据新值悄悄创建了一个新对象,然后将这个对象的地址返回给原来类的引用。这个创建过程虽说是完全自动进行的,但它毕竟占用了更多的时间。在对时间要求比较敏感的环境中,会带有一定的不良影响。

再修改原来代码:

String str1 = 'abc';
String str2 = 'abc';

str1 = 'bcd';

String str3 = str1;
System.out.println(str3); //bcd

String str4 = 'bcd';
System.out.println(str1 == str4); //true

str3这个对象的引用直接指向str1所指向的对象(注意,str3并没有创建新对象)。当str1改完其值后,再创建一个String的引用str4,并指向因str1修改值而创建的新的对象。可以发现,这回str4也没有创建新的对象,从而再次实现栈中数据的共享。

我们再接着看以下的代码。

String str1 = new String('abc');
String str2 = 'abc';
System.out.println(str1==str2); //false

创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。

String str1 = 'abc';
String str2 = new String('abc');
System.out.println(str1==str2); //false

创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。

以上两段代码说明,只要是用new()来新建对象的,都会在堆中创建,而且其字符串是单独存值的,即使与栈中的数据相同,也不会与栈中的数据共享。

3. 数据类型包装类的值不可修改。不仅仅是String类的值不可修改,所有的数据类型包装类都不能更改其内部的值。

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8869977/viewspace-899145/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/8869977/viewspace-899145/

<think>好的,我现在需要帮助用户解决如何将Java中的Timestamp类型转换为String类型的问题。用户已经提供了几个相关的引用,我需要仔细阅读这些引用,看看有没有可用的信息。 首先看引用[1],里面有一个将Timestamp转换为Date的示例,使用了timestamp.getTime()来获取毫秒数,然后创建Date对象。这可能对转换过程有帮助,但用户的目标是转成String,所以可能需要结合日期格式化。 然后引用[2]是关于将时间戳转StringString转时间戳的例子。这里用到了SimpleDateFormat,用户可能需要似的步骤,但需要调整以处理Timestamp对象。示例中的代码展示了如何解析String到Date,再获取时间戳,但用户需要的是相反的操作:从Timestamp到String。 引用[3]提到使用java.time包处理时间,特别是处理时区的问题。这可能涉及到更现代的如DateTimeFormatter和LocalDateTime,这些在Java 8及以上版本中可用。用户可能不知道新旧API的区别,所以需要比较两种方法的优劣。 现在,用户的问题是将Timestamp转换为String。我需要考虑两种方式:传统的SimpleDateFormat和新的java.time API。首先,Timestamp是java.sql.Timestamp,它继承自java.util.Date,所以传统方法可以对其直接使用。而java.time则需要将Timestamp转换为Instant或LocalDateTime,再进行格式化。 步骤大致如下: 1. 创建Timestamp对象,比如通过当前时间。 2. 定义日期格式的字符串,比如"yyyy-MM-dd HH:mm:ss"。 3. 使用SimpleDateFormat或DateTimeFormatter来格式化Timestamp为String。 需要注意的是,SimpleDateFormat是线程不安全的,而DateTimeFormatter是线程安全的,推荐后者。另外,处理时区时可能需要明确设置时区,特别是在转换时避免时区问题。 在引用[2]中,用户展示了使用SimpleDateFormat的例子,但那是将String转时间戳,而这里需要的是反向操作。所以可以调整代码,使用format方法而不是parse方法。 另外,引用[3]提到使用java.time处理时区问题,比如ZonedDateTime,这可能对需要时区转换的情况有帮助。如果用户的时间戳需要特定时区的表示,可能需要用到这个。 现在需要写示例代码,两种方式都要展示。传统方式和java.time方式。同时需要指出两者的区别和推荐使用的情况。 可能的问题点是,用户可能不清楚如何将Timestamp转换为java.time的对象。Timestamp有一个toInstant()方法,可以将Timestamp转换为Instant,然后可以转换为LocalDateTime或其他时区时间。 此外,异常处理方面,SimpleDateFormat的parse方法会抛出ParseException,但format方法不会,所以在格式化Timestamp为String时不需要try-catch,但为了代码的健壮性,可能要考虑格式字符串的正确性。 总结步骤: 传统方法: 1. 创建Timestamp实例。 2. 创建SimpleDateFormat实例,指定格式。 3. 使用format方法将Timestamp转换为StringJava 8+方法: 1. 创建Timestamp实例。 2. 转换为LocalDateTime或Instant。 3. 使用DateTimeFormatter格式化。 在代码示例中,需要处理可能的时区问题,特别是如果用户需要特定时区的显示。但假设用户只需要默认时区,可以省略时区的设置,或者明确说明如何设置时区。 最后,需要检查代码是否正确,比如在传统方法中,Timestamp可以直接传给SimpleDateFormat的format方法,因为它是Date的子。在java.time方法中,需要调用toLocalDateTime()方法,或者使用Instant结合时区信息。 现在编写代码示例,并解释每个步骤。同时,回答用户的问题时,要结构清晰,分点说明两种方法,并给出建议。</think>### Java中将Timestamp转换为String的实现方法 在Java中将`java.sql.Timestamp`转换为`String`需通过**日期格式化工具**实现。以下是两种常用方法:使用传统`SimpleDateFormat`或Java 8+的`DateTimeFormatter`。 --- #### 方法1:使用SimpleDateFormat(传统方式) ```java import java.sql.Timestamp; import java.text.SimpleDateFormat; public class TimestampToStringExample { public static void main(String[] args) { // 1. 创建Timestamp对象(示例为当前时间) Timestamp timestamp = new Timestamp(System.currentTimeMillis()); // 2. 定义日期格式 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 3. 格式化Timestamp为String String dateString = sdf.format(timestamp); System.out.println("Formatted String: " + dateString); } } ``` - **关键点**: 1. `SimpleDateFormat`是线程不安全的,需避免在多线程中共享实例[^2]。 2. 格式模式需与实际需求匹配(如`"yyyy-MM-dd"`仅保留日期)。 --- #### 方法2:使用DateTimeFormatter(Java 8+推荐) ```java import java.sql.Timestamp; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class TimestampToStringJava8 { public static void main(String[] args) { // 1. 创建Timestamp对象 Timestamp timestamp = new Timestamp(System.currentTimeMillis()); // 2. 转换为LocalDateTime(自动处理时区为系统默认) LocalDateTime localDateTime = timestamp.toLocalDateTime(); // 3. 定义格式化器 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 4. 格式化输出 String dateString = localDateTime.format(formatter); System.out.println("Formatted String: " + dateString); } } ``` - **优势**: - `DateTimeFormatter`是线程安全的[^3]。 - 支持更灵活的时区处理(如添加`.withZone(ZoneId.of("Asia/Shanghai"))`)。 --- #### 关键区别与建议 | 特性 | SimpleDateFormat | DateTimeFormatter | |--------------------|------------------------|-------------------------| | 线程安全性 | 不安全 | 安全 | | API版本 | Java 1.1+ | Java 8+ | | 时区处理 | 需手动设置 | 内置时区支持 | | **推荐场景** | 旧项目兼容 | 新项目开发 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值