String是一个字符串,但是字符串的内容不可改变,改变的只是内存地址的指向,那么如果现在想要让字符串的内容可以修改,则必须使用StringBuffer类完成。
在String中使用“+”号进行字符串的连接,在StringBuffer中使用append()方法进行字符串的连接。在使用StringBuffer是不能像String那样可以直接使用字符串进行复制操作,必须通过关键字new开辟对象才可以使用,之后使用append()方法。
package com.java.stringBufferDemo; public class StringBufferDemo01 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("Hello"); stringBuffer.append(" ").append("World").append(" ").append("!!!"); System.out.println(stringBuffer); } } |
在程序中就只有简单的将“+”替换成了append()方法而已,但是需要说明的是,String与StringBuffer没有直接的关系。所以如果想将StringBuffer类型的对象转换成String类型,就必须使用toString()方法完成。
package com.java.stringBufferDemo; public class StringBufferDemo02 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("Hello"); stringBuffer.append(" ").append("World").append(" ").append("!!!"); String string = stringBuffer.toString(); System.out.println(string); } } |
实际上,一般情况下StringBuffer问问都用在频繁修改字符串的地方。
package com.java.stringBufferDemo; public class StringBufferDemo02 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer(); fun(stringBuffer); for (int i = 1; i <= 1000; i++) { if(i % 10 == 1){ stringBuffer.append("\n"); } stringBuffer.append(i + "\t"); } System.out.println(stringBuffer); } public static void fun(StringBuffer stringBuffer) { stringBuffer.append("Hello").append("\n"); } } |
在StringBuffer中提供了大量的操作方法,有些方法就是雨String类似的关键是查看那些新增加的方法。
package com.java.stringBufferDemo; public class StringBufferAPIDemo01 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("Hello"); stringBuffer.append(" ").append("World").append(" ").append("!!!"); stringBuffer.insert(1, "***"); stringBuffer.insert(0, "+++"); System.out.println(stringBuffer); } } |
package com.java.stringBufferDemo; public class StringBufferAPIDemo02 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("Hello"); stringBuffer.append(" ").append("World").append(" ").append("!!!"); stringBuffer.insert(1, "***"); stringBuffer.insert(0, "+++"); System.out.println(stringBuffer); System.out.println(stringBuffer.delete(0, 9)); } } |
package com.java.stringBufferDemo;
public class StringBufferAPIDemo02 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("Hello"); stringBuffer.append(" ").append("World").append(" ").append("!!!"); System.out.println(stringBuffer.reverse()); // 将内容翻转 } } |
每一个JVM启动的时候伺机上都对应了一个Runtime实例,表示运行时,但是此类的构造方法被私有化,则此类的内部肯定有一个方法可以取得本类的实例。
实际上可以通过Runtime类直接运行本机程序。
·方法:public Process exec(String command) throws IOException
范例:运行本机上的计算器程序
package com.java.runtimeDemo; public class RuntimeDemo01 { public static void main(String[] args) throws Exception { Runtime runtime = Runtime.getRuntime(); // 单例设计 runtime.exec("calc"); // 执行程序 } } |
可以让指定的程序进行自动的关闭。exec()方法返回一个Process类的实例,表示一个进程的队形,如果想要关闭,则使用此类中的:public abstract void destroy()
package com.java.runtimeDemo; public class RuntimeDemo02 { public static void main(String[] args) throws Exception { Runtime runtime = Runtime.getRuntime(); // 单例设计 Process process = runtime.exec("calc"); // 执行程序 Thread.sleep(2000); // 程序运行2秒 process.destroy(); // 关闭进程 } } |
在Runtime类中可以通过maxMemory()、freeMemory()、totalMemory()取得系统的内存信息,之后也可以通过gc()方法强制性的程序释放掉所有的垃圾空间。
package com.java.runtimeDemo; public class RuntimeDemo03 { public static void main(String[] args) throws Exception { Runtime runtime = Runtime.getRuntime(); // 单例设计 System.out.println("1.最大可用内存:" + runtime.maxMemory()); System.out.println("1.空闲内存空间:" + runtime.freeMemory()); System.out.println("1.总共内存空间:" + runtime.totalMemory()); String string = ""; for(int i = 0; i <= 10000; i++){ string += i; // 会产生大量的垃圾 } System.out.println("2.空闲内存空间:" + runtime.freeMemory()); runtime.gc(); // 运行垃圾回收 System.out.println("3.空闲内存空间:" + runtime.freeMemory()); } } |
运行结果:
1.最大可用内存:933953536 1.空闲内存空间:62319360 1.总共内存空间:62980096 ========================= 2.空闲内存空间:305506256 ========================= 3.空闲内存空间:390997696 |
System是一个系统类,是一个陪伴我们时间最长的类,例如:System.out.println()就是此类中提供的操作。
使用此类可以取得计算的时间,例如,想知道一个程序执行时一共花费了多少时间。
·得到当前的时间:public static long currentTimeMillis()
package com.java.systemDemo; public class SystemDemo01 { public static void main(String[] args) { long begin = System.currentTimeMillis(); String string = ""; for (int i = 0; i <= 10000; i++) { string += i; // 会产生大量的垃圾 } long end = System.currentTimeMillis(); System.out.println("程序执行的时间:" + (end - begin) + "ms"); } } |
在System类中有一个gc()方法:public static void gc(),运行垃圾回收器。调用 System.gc() 实际上等效于调用: Runtime.getRuntime().gc()
如果一个对象不用的话,则就有可能进行垃圾的回收,但是如果一个对象在被回收之前需要做一些收尾的工作。又该怎么办呢???
在Object类中存在一个方法,此方法在对象被回收前调用:
·protected void finalize() throws Throwable
package com.java.systemDemo; public class SystemDemo02 { public static void main(String[] args) throws Throwable { Person person = new Person("Harry", 80); person.finalize(); person = null; System.gc(); } } class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return "name:" + this.name + ",age:" + this.age; } protected void finalize() throws Throwable { System.out.println("我被回收了。。。" + "(" + this + ")"); } } |
但是从一把开发的角度来讲,很少有专门的开发在对象的回收前进行操作的,所以此操作理解即可。
面试题:说明 final、finally、finalize的区别。。。
国际化程序:一套程序可以同时适应多个国家的语言要求,那么这样的程序成为国际化程序。如果想要红丝线国际化程序,则必须依靠Local、ResourceBoundle、MessageFormat及各类完成。并结合属性文件(*.properties)。
Local实际上非常好理解,表示一个地区,也就是说在国际化程序中提供Local指定当前所在地区。世界上各个国家都存在一个国家的编号,例如:
·中国:zh_CN ·美国en_US
实际上这些代码根本就没有必要记住。因为在浏览器中谁都有指示。使用的时候可以直接查。打开IE浏览器:工具àInternet选项à语言à添加。即可。
如果想要创建Local类的对象有两种方式:
·直接去的本机的语言:public static Locale getDefault()
·通过构造方法直接指定一种语言:public Locale(String language, String country)
但是如果过想要实现程序的国际化只靠Local类是不够的,需要哟个配合的属性文件存在,一个地区的Local对象应该对应一个不同的属性文件。
找到属性文件之后,下一步就需要将内容取出,所有的内容都需要ResourceBundle来读取。
此类是在java.util中定义的。使用时会通过里面的静态方法取得实例,有两种方式:
·通过本机的Local取得属性文件:
·public static final ResourceBundle getBundle(String baseName)
·通过指定的Local取得:
一般来说,使用第二种是比较常用的。下面通过一段代码来演示如何访问属性文件
属性文件:Message.properties(使用IDE开发,属性文件放在工程bin目录下)
Info = 你好 !!! |
其中‘Info’为key,‘你好’为value。程序操作时通过key找到value。
在使用ResourceBundle读取的时候根据key进行读取,方法是:
·public final String getString(String key)
package com.java.localDemo; import java.util.Locale; import java.util.ResourceBundle; public class LocalDemo01 { public static void main(String[] args) { Locale locale = Locale.getDefault(); // 得到默认的Local /** * 要找到Message的属性,此时省略了后缀,并指定了区域 */ ResourceBundle rb = ResourceBundle.getBundle("Message", locale); String value = rb.getString("Info"); // 通过Info找到内容 System.out.println("内容:" + value); } } |
此时,如果使用命令行编译运行,属性文件使用Notepad编写,内容却是读进来了,但是内容在显示的时候出现了乱码。如果使用IDE编写的话,属性文件不能输入中文,自动回转换为代码。因为对于属性文件来讲,里面是不能够有中文的,如果出此案中文,则必须进行转码操作,转换为UNICODE编码。
在JDK中提供了一个转换工具,可以讲文字转换为16进制编码,此工具在JDK暗转目录下的:bin\native2ascii.exe。
现在将上面的属性文件进行修改。
Info = \u4F60\u597D \uFF01\uFF01\uFF01 |
那么此时再次读取,发现内容可以正常显示了。
现在假设,如果是中国则显示 你好!!!,如果是英语国家则显示Hello !!!。先要完成此程序,则首先应该建立两个属性文件,这两个属性文件有命名要求:属性名称_区域名称.properties
·中文:Message_zh_CN.properties ·英文:Message_en_US.properties
属性文件:
Info = Hello ! |
Info = \u4F60\u597D \uFF01 |
主程序:
package com.java.localDemo; import java.util.Locale; import java.util.ResourceBundle; public class LocalDemo02 { public static void main(String[] args) { Locale locale_zh = new Locale("zh", "CN"); // 指定中文环境 Locale locale_en = new Locale("en", "US"); // 指定英文环境 /** * 要找到Message的属性,此时省略了后缀,并指定了区域 */ ResourceBundle rb_zh = ResourceBundle.getBundle("Message", locale_zh); ResourceBundle rb_en = ResourceBundle.getBundle("Message", locale_en); /** * 通过Info找到内容 */ String value_zh = rb_zh.getString("Info"); String value_en = rb_en.getString("Info"); System.out.println("中文内容:" + value_zh); System.out.println("英文内容:" + value_en); } } |
在整个国际化程序中,属性文件时最终要的,因为可以根据不同的语言区域进行自动的文字装载。
之前所有的内容实际上在属性文件中保存的值都是固定的,现在如果希望某些内容进行动态显示,
例如:年号,Xxx!
那么此时就可以使用占位符的方式完成,在属性文件中加入“{编号}”即可。
Message_zh_CN.properties |
Info = \u4F60\u597D \uFF01{0}{1}{2} |
Message_en_US.properties |
Info = Hello !{0}{1}{2} |
之后就可以使用MessageFormat进行文字的格式化操作。此类在java.text包中定义,使用如下方法完成内容的增加:
·public static String format(String pattern,Object... arguments)
package com.java.localDemo; import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; public class LocalDemo03 { public static void main(String[] args) { Locale locale_zh = new Locale("zh", "CN"); // 指定中文环境 Locale locale_en = new Locale("en", "US"); // 指定英文环境 // 要找到Message的属性,此时省略了后缀,并指定了区域 ResourceBundle rb_zh = ResourceBundle.getBundle("Message", locale_zh); ResourceBundle rb_en = ResourceBundle.getBundle("Message", locale_en); // 通过Info找到内容 String value_zh = rb_zh.getString("Info"); String value_en = rb_en.getString("Info"); System.out.println("中文内容:" + MessageFormat.format( value_zh, "\t\t张庭括" ,"\t\t男", "\t20 ")); System.out.println("英文内容:" + MessageFormat.format( value_en, "\tZhang Tingkuo" ,"\tMale", "\tTwenty ")); } } |
在程序中可以通过类存储全部的资源内容,那么此类必须继承ListResourceBundle。
package com.java.localDemo; import java.util.ListResourceBundle; public class Message_zh_CN extends ListResourceBundle { Object data[][] = { {"Info", "你好,{0},年龄:,{1}"} }; protected Object[][] getContents() { return this.data; } } |
package com.java.localeDemo; import java.util.ListResourceBundle; public class Message_en_US extends ListResourceBundle { Object data[][] = { {"Info", "Hello,{0},Age:,{1}"} }; protected Object[][] getContents() { return this.data; } } |
通过观察,如果在一个classpath同时存在:
·Message.properties
·Message_zh_CN.properties
·Message.java
·Message_zh_CN.java
调用的顺序是:
1.Message_zh_CN.java
2.Message.java
3.Message.properties
4.Message_zh_CN.properties
但是从实际的开发角度来看,一般不会使用一个类来表示一个资源文件的内容,都是使用properties文件保存,
在Java中对日期的显示进行了很好的支持,使用Date、DateFormat、SimpleDateFormat、Calendar等类都可以取得日期。
java.util.Date是一个由系统提供的日期操作类,此类的操作非常简单,同时也是一个非常很总要的类,在日后的很多开发中,都会使用到此类。
package com.java.dateDemo; import java.util.Date; public class DateDemo { public static void main(String[] args) { System.out.println(new Date()); } } |
日期:
Wed Aug 08 17:50:48 CST 2012 |
此时日期已经可以正常显示了,但是日期的显示格式并不符合国人的习惯。中国人的习惯更倾向于:
2012-08-08 17:50 星期三 |
通过此类可以讲时间精确到毫秒,Calendar类的定义:
public abstract class Calendar extends Object implements Serializable, Cloneable, Comparable<Calendar> |
此类是一个抽象类,则使用时必须依靠其子类:
package com.java.dateDemo; import java.util.Calendar; import java.util.GregorianCalendar; public class CalendarDemo { public static void main(String[] args) { Calendar calendar = new GregorianCalendar(); System.out.println("年: " + calendar.get(Calendar.YEAR)); System.out.println("月: " + (calendar.get(Calendar.MONTH) + 1)); System.out.println("日: " + calendar.get(Calendar.DAY_OF_MONTH)); System.out.println("时: " + calendar.get(Calendar.HOUR_OF_DAY)); System.out.println("分: " + calendar.get(Calendar.MINUTE)); System.out.println("秒: " + calendar.get(Calendar.SECOND)); System.out.println("毫秒: " + calendar.get(Calendar.MILLISECOND)); } } |
在程序的开发中基本上都会大量的使用取出日期的操作,而如果每次都想之前那样取出的日期的话,则会很麻烦,所以最好可以设计一个类,那么此类可以直接返回日期,返回的日期包含以下几种形式:
·形式一:2012-08-08
·形式二:2012-08-08 18-40 123
·形式三:2012年08月08日
·形式四:2012年08月08日 16时40分123毫秒
package com.java.dateDemo; import java.util.Calendar; import java.util.GregorianCalendar; public class DateTime { private Calendar calendar = new GregorianCalendar(); // 实例化Calendar对象 public String getDate() {// 2009-03-02 StringBuffer buf = new StringBuffer(); buf.append(calendar.get(Calendar.YEAR)).append("-"); buf.append(this.addZero((calendar.get(Calendar.MONTH) + 1), 2)).append( "-"); buf.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2)); return buf.toString(); } public String getDateTime() {// 2009-03-02 16:19:34.123 StringBuffer buf = new StringBuffer(); buf.append(this.getDate()).append(" "); buf.append(this.addZero(calendar.get(Calendar.HOUR_OF_DAY), 2)).append( ":"); buf.append(this.addZero(calendar.get(Calendar.MINUTE), 2)).append(":"); buf.append(this.addZero(calendar.get(Calendar.SECOND), 2)).append("."); buf.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3)); return buf.toString(); } public String getDateComplete() {// 2009年03月02日 StringBuffer buf = new StringBuffer(); buf.append(calendar.get(Calendar.YEAR)).append("年"); buf.append(this.addZero((calendar.get(Calendar.MONTH) + 1), 2)).append("月"); buf.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2)).append("日"); return buf.toString(); } public String getDateTimeComplete() {// 2009年03月02日16时19分34秒123毫秒 StringBuffer buf = new StringBuffer(); buf.append(this.getDateComplete()); buf.append(this.addZero(calendar.get(Calendar.HOUR_OF_DAY), 2)).append("时"); buf.append(this.addZero(calendar.get(Calendar.MINUTE), 2)).append("分"); buf.append(this.addZero(calendar.get(Calendar.SECOND), 2)).append("秒"); buf.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3)).append("毫秒"); return buf.toString(); } private String addZero(int temp, int len) { StringBuffer str = new StringBuffer(); str.append(temp);// 加入数字 while (str.length() < len) { str.insert(0, 0); // 在第一个位置加上字母0 } return str.toString(); } public static void main(String args[]) { System.out.println(new DateTime().getDateTimeComplete()); } } |