十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
国际化的英文为Internationalization,这个也太长了,所以它又称为I18n(英文单词 internationalization的首末字符i和n,18为中间的字符数)。
专注于为中小企业提供成都网站设计、网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业承留免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上千多家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
除了i18n还有L10n(localization),g11n(globalization),还有m17n(multilingualization),它们的区别是:
i18n支持多种语言,但是同一时间只能是英文和一种选定的语言,例如英文+中文、英文+德文、英文+韩文等等;
L10n(localization),支持2种语言,英文和另外一种语言(例如中文);
g11n(globalization),简单的理解可以认为g11n = i18n + L10n。
m17n(multilingualization)可以在同一时间支持多种语言,例如你可以在一个页面里看到中文、英文、德文和韩文。
为了使不同国家地区的人使用到适应他们环境和语言的软件或网站,国际化成为了Java的必要因素之一。
国际化机制在软件开发过程中,使得软件与特定的语言或地区脱钩。当我们做的软件被移植到其他国家时,不必更改软件本身的代码就可以适应当地区的使用了,所以,国际化是必须的。
那么在Java中如何实现国际化呢?
通过学习后,我也了解了一些必要的入门知识。
首先,我们可以通过测试代码获得本机操作系统的默认语言和区域。
查看默认语言和区域:
测试代码:
1 /**
2 * @author 巨亚红
3 * @date 2014-3-18 下午2:47:06
4 * @版本 V1.0 作者: 时间: 修改:
5 * @param args
6 */
7 public static void main(String[] args) {
8 Locale defaultLocale=Locale.getDefault();
9 System.out.println("country="+defaultLocale.getCountry());
10 System.out.println("language="+defaultLocale.getLanguage());
11 }
测试结果:
如果将默认地区修改为美国的话,测试结果为:
我们需要将硬编码文本转移到外部的资源文件里,建立两个国际化资源文件:
名称=基本名称+Locale
1、设置资源文件。
MessgesBundle_en_US.properties:
k1=hello
k2=good bye
MessgesBundle_zh_CN.properties:
k1=\u4F60\u597D
k2=\u518D\u89C1
2、利用ResourceBundle.getBundle(baseName, locale)来找到MessgesBundle_en_US.properties文件。
ResourceBundle rb=ResourceBundle.getBundle("MessgesBundle", defaultLocale);
3、拿到k1和k2的value值。
System.out.println("k1="+rb.getString("k1"));
System.out.println("k2="+rb.getString("k2"));
结果是:
当前的地区设置成为英语(美国):
当前的地区设置成为中文(简体,中国):
4、占位符的使用。
设置当前Locale
//Locale currentLocale=new Locale("zh", "CN");
Locale currentLocale=new Locale("en", "US");
添加占位符:
利用类MessageFormat
1 Locale currentLocale=new Locale("en", "US");
2 ResourceBundle rb=ResourceBundle.getBundle("MessgesBundle", currentLocale);
3 MessageFormat mf=new MessageFormat(rb.getString("k1"));
4 System.out.println("k1="+mf.format(new Object[]{"Jessica"}));
结果为:
如果改成中文:
1 Locale currentLocale=new Locale("zh", "CN"); //中文
2 ResourceBundle rb=ResourceBundle.getBundle("MessgesBundle", currentLocale);
3 MessageFormat mf=new MessageFormat(rb.getString("k1"));
4 System.out.println("k1="+mf.format(new Object[]{"巨亚红"}));
结果为:
5、设置缺省国际化资源文件。
上面中我们设置的两个Locale已有资源文件,但是如果我们随便设置一个Locale,如果没有它对应的资源文件怎么办?那么就需要设置一个缺省的国际化资源文件了。只要添加一个名为MessgesBundle.properties的资源文件可以了,在里面进行相应的设置就OK了。
注意点:
缺省的Locale是由操作系统决定的。
Locale由语言和国家代码构成。
国际化资源文件是由baseName+Locale构成,如: MessgesBundle_en_US.properties
缺省的国际化资源文件是由baseName.properties命名的,如:MessgesBundle.properties
如果资源文件放在了包里,那么baseName就要加上包名了,否则找不到。
附上出处链接:
package com.lp.test;
public class StringTest {
public static void main(String[] args) {
// TODO code application logic here
//打印main方法参数
if (args.length 0) {
for (int i = 0; i args.length; i++) {
System.out.println(args[i]);
}
} else {
System.out.println("No args.");
}
String str = "12345";
//将str拆分为单个char输出
for (int i = 0; i str.length(); i++) {
System.out.print(str.charAt(i) + " ");
}
System.out.println("");
//截取str前四位
str = str.substring(0, 4);
System.out.println(str);
//将截取后的str与"77777"进行拼接
str = str.concat("77777");
System.out.println(str);
//输出7在str中第一次出现的位置
int index = str.indexOf('7');
System.out.println(index);
//获取7在str中最后一次出现的位置
int lastIndex = str.lastIndexOf('7');
System.out.println(lastIndex);
//将str中的7全部换为6
str = str.replace('7', '6');
System.out.println(str);
//将str中第一次出现的"6666"置换为"5"
str = str.replaceAll("6666", "5");
System.out.println(str);
//初始化一个包含"12345"的字符串缓冲对象
StringBuilder strb = new StringBuilder("12345");
//循环输出字符串缓冲对象的内容
for (int i = 0; i strb.length(); i++) {
System.out.print(strb.charAt(i) + " ");
}
System.out.println("");
//删除strb中索引为4的字符
strb.deleteCharAt(4);
System.out.println(strb);
//在删除字符后的strb中拼接"77777"
strb.append("77777");
System.out.println(strb);
//在索引为4芳容位置上插入"56";
strb.insert(4, "56");
System.out.println(strb);
//颠倒strb中的字符顺序
strb.reverse();
System.out.println(strb);
String hello = "HelloWord";
//将hello字符串转换为全小写
System.out.println(hello.toLowerCase());
//将hello字符串转换为全大写
System.out.println(hello.toUpperCase());
}
}
使用java提供的国际化功能就可以了。不过建议你使用框架技术中的国际化,框架技术中的国际化都做过封装,实现起来相对简单的多。只需要简单的配置就可以实现中英文或者其他语言的切换了!~
虚拟机:指以软件的方式模拟具有完整硬件,VM概念
虚拟机:指以软件的方式模拟具有完整硬件系统功能、运行在一个完全隔离环境中的完整计算机系统 ,是物理机的软件实现。常用的虚拟机有VMWare,Visual Box,Java Virtual Machine(Java虚拟机,简称JVM)。
Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够"一次编译,到处运行"的原因。
Java虚拟机阵营:Sun HotSpot VM、BEA JRockit VM、IBM J9 VM、Azul VM、Apache Harmony、Google Dalvik VM、Microsoft JVM…
启动流程


JVM由三个主要的子系统构成:
1.类加载器子系统
2.运行时数据区(内存)
3.执行引擎


JVM原理
JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器。它是一种基于下层的操作系统和硬件平台并利用软件方法来实现的抽象的计算机,可以在上面执行java的字节码程序。
java编译器只需面向JVM,生成JVM能理解的代码或字节码文件。Java源文件经编译器,编译成字节码程序,通过JVM将每一条指令翻译成不同平台机器码,通过特定平台运行。
JVM执行程序的过程 :
I.加载.class文件
II.管理并分配内存
III.执行垃圾收集
JRE(java运行时环境)包含JVM的java程序的运行环境
JVM是Java程序运行的容器,但是他同时也是操作系统的一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间。
JVM在整个jdk中处于最底层,负责与操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也叫虚拟计算机.操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境。
1.创建JVM装载环境和配置
2.装载JVM.dll
3.初始化JVM.dll并挂接到JNIENV(JNI调用接口)实例
4.调用JNIEnv实例装载并处理class类。
寄存器
所有的CPU均包含用于保存系统状态和处理器所需信息的寄存器组。如果虚拟机定义较多的寄存器,便可以从中得到更多的信息而不必对栈或内存进行访问,这有利于提高运行速度。然而,如果虚拟机中的寄存器比实际CPU的寄存器多,在实现虚拟机时就会占用处理器大量的时间来用常规存储器模拟寄存器,这反而会降低虚拟机的效率。针对这种情况,JVM只设置了4个最为常用的寄存器。它们是:
pc程序计数器
optop操作数栈顶指针
frame当前执行环境指针
vars指向当前执行环境中第一个局部变量的指针
所有寄存器均为32位。pc用于记录程序的执行。optop,frame和vars用于记录指向Java栈区的指针。寄存器
栈结构
作为基于栈结构的计算机,Java栈是JVM存储信息的主要方法。当JVM得到一个Java字节码应用程序后,便为该代码中一个类的每一个方法创建一个栈框架,以保存该方法的状态信息。每个栈框架包括以下三类信息:
局部变量
执行环境
操作数栈
局部变量用于存储一个类的方法中所用到的局部变量。vars寄存器指向该变量表中的第一个局部变量。
执行环境用于保存解释器对Java字节码进行解释过程中所需的信息。它们是:上次调用的方法、局部变量指针和操作数栈的栈顶和栈底指针。执行环境是一个执行一个方法的控制中心。例如:如果解释器要执行iadd(整数加法),首先要从frame寄存器中找到当前执行环境,而后便从执行环境中找到操作数栈,从栈顶弹出两个整数进行加法运算,最后将结果压入栈顶。
操作数栈用于存储运算所需操作数及运算的结果。
运行数据
JVM定义了若干个程序执行期间使用的数据区域。这个区域里的一些数据在JVM启动的时候创建,在JVM退出的时候销毁。而其他的数据依赖于每一个线程,在线程创建时创建,在线程退出时销毁。分别有程序计数器,堆,栈,方法区,运行时常量池。
运行过程
上面对虚拟机的各个部分进行了比较详细的说明,下面通过一个具体的例子来分析它的运行过程。
虚拟机通过调用某个指定类的方法main启动,传递给main一个字符串数组参数,使指定的类被装载,同时链接该类所使用的其它的类型,并且初始化它们。新建一java源文件并取名HelloApp.java,内容如下:
class HelloApp {
public static void main(String[] args) {
System.out.println("Hello World!");
for (int i = 0; i args.length; i++ ) {
System.out.println(args);
}
}
}
在命令模式下输入:javac HelloApp.java 进行编译,这时同目录下会产生一个编译后的文件:HelloApp.class
然后在命令行模式下键入:java HelloApp run virtual machine
将通过调用HelloApp的方法main来启动java虚拟机,传递给main一个包含三个字符串"run"、"virtual"、"machine"的数组。我们略述虚拟机在执行HelloApp时可能采取的步骤。


JVM虚拟机运行过程
开始试图执行类HelloApp的main方法,发现该类并没有被装载,也就是说虚拟机当前不包含该类的二进制代表,于是虚拟机使用ClassLoader试图寻找这样的二进制代表。如果这个进程失败,则抛出一个异常。类被装载后同时在main方法被调用之前,必须对类HelloApp与其它类型进行链接然后初始化。链接包含三个阶段:检验,准备和解析。检验检查被装载的主类的符号和语义,准备则创建类或接口的静态域以及把这些域初始化为标准的默认值,解析负责检查主类对其它类或接口的符号引用,在这一步它是可选的。类的初始化是对类中声明的静态初始化函数和静态域的初始化构造方法的执行。一个类在初始化之前它的父类必须被初始化。