1. Java面向对象基本概念
Java基本上是面向对象的程序设计语言, 除了一些简单类型(primitive)的变量以外,一切都是对象, 程序是对象的组合, 每个对象都有自己的空间, 并且每个对象都有一种类型, 同一类所有对象都能接受相同的消息。 下面只对Java中对象的结构作简单的说明:
类(class): class是定义类的关键字, 类中包含类变量, 方法, 内部类, 内部接口等。由class可以生成类的实例, 即一个个对象。 如果一个类的成员被定义成static的,则这个成员不专属于任何对象, 而是属于这个类, 所有的对象共享这个成员。
抽象类(abstract class): 抽象类不能直接生成一个实例, 抽象类中必需有方法是abstract的,抽象类的意思就是它实现了一部分的方法, 而定义为abstract的方法则需要在它的字类中去实现。
接口(interface): 接口可以理解为纯抽象的类, 它的每个方法都是未实现的, 它可以有成员变量, 但必须是static的。 一个类如果从这个接口继承(implements)则它必须实现这个接口的所有方法。
继承类用关键字:extends,继承接口用关键字:implements。 一个类只能从一个类继承下来, 但可以从多个接口继承(类似于C++的多重继承)。 字类可以覆盖父类的方法(method), 但不能覆盖父类的成员变量(field)。 如果父类的方法为final或static的则不能被覆盖。类的初始化顺序是, 如果有父类, 则先初始化父类的field,然后执行父类的构造函数, 如果子类没有显式的去调父类的构造函数则缺省的会去调父类的无参数构造函数。 然后是子类的field与构造函数的初始化。
public interface SuperInterface {
public staitc String SOME_FLAG = “1”;
public void someMethod();
}
public Class SuperClass {
{ System.out.println(“init SuperClass field”);}
public SuperClass() {System.out.println(“init SuperClass Constructor”); }
public void runMethod() { System.out.println(“run SuperClass runMethod()”); }
}
public Class SubClass extends SuperClass implements SuperInterface {
{ System.out.println(“init SubClass field”); }
public SubClass() {System.out.println(“init SubClass Constructor”); }
public void someMethod() {System.out.println(“run SubClass someMethod()”); }
public void runMethod() {System.out.println(“run SubClass runMethod()”); }
}
有以下test代码:
public class Test {
public void main(String[] args) {
SubClass sub = new SubClass();
sub. runMethod();
}
}
则会输出:
init SuperClass field
init SuperClass Constructor
init SubClass field
init SubClass Constructor
run SubClass runMethod()
2.System
System类位于package java.lang下面, 凡是此package下面的类我们可以直接引用无需先import进来, 因为JVM缺省就load了这下面的所有class。
System包含了一些我们常用的方法与成员变量。 System不能被实例化, 所有的方法都可以直接引用。 主要作用大致有:
输入输出流:
(PrintStream) System.out (标准终端输出流),
(PrintStream) System.err(标准错误输出流),
(InputStream) System.in(标准输入流)。
我们还可以重定向这些流, 比如将所有的System.out的输出全部重定向至一文件中去。
System.setOut(PrintStream) 标准输出重定向
System.setErr(PrintStream) 标准错误输出重定向
System.setIn(InputStream) 标准输入重定向
取当前时间:
System.currentTimeMillis() 所取到的时间是从1970/01/01以来1/1000秒计算的long型值。这个值可以转换至Date或Timestamp值。 它一般还可以用来计算程序执行的时间。例:
long beginTime = System. currentTimeMillis();
…
…
System.out.println(“run time = ” + (System. currentTimeMillis() – beginTime));
数组拷贝:
System.arraycopy(Object src, int src_position, Object dst, int dst_position, int length)
src: 源数组。
src_position: 源数组拷贝的起始位置。
dst: 目标数组
dst_position: 拷贝至目标数组的起始位置
length: 拷贝元素的长度
利用System.arraycopy进行数组的拷贝效率是最高的, 一般情况下我们自己很少直接用到这个方法,但在集合类的内部中都大量使用了这个方法。
例:
int[] array1 = {1, 2, 3, 4, 5};
int[] array2 = {4, 5, 6, 7, 8};
int array3 = new int[8];
System.arraycopy(array1, 0, array3, 0, 5);
System.arraycopy(array2, 2, array3, 5, 3);
此时array3 = {1, 2, 3, 4, 5, 6, 7, 8}
这比用for循环来进行赋值效率要高。
存取系统的Properties:
System.getProperties():取得当前所有的Properties, Properties将在后面的集合一节进行详细的论述。
System.setProperties(Properties props):设置系统的Properties。
System.getProperty(String key): 根据一个键值来取得一个Property。
System.setProperty(String key, String value): 设置系统的一个Property。
JVM起动的时候将会有一些缺省的Properties值, 例如:
java.version Java运行环境版本
java.home Java主目录 installation directory
java.class.path Java 的class path
java.ext.dirs Java的扩展目录路径
file.separator 文件分隔符("/" on UNIX)
path.separator 路径分隔符(":" on UNIX)
line.separator 行分隔符 ("\n" on UNIX)
user.name 用户名
user.home 用户主目录
user.dir 用户当前工作目录
更详细的信息请参照Java API。 另外在起动一个java程序的时候可以通过-D来设置系统的Property, 比如 java –Dejb.file=ejb_Test PrintTest 在PrintTest里面就可以通过System.getProperty(“ejb.file”)来取得值ejb_Test。
其它
System. loadLibrary(String libname): 加载native的动态库。 可以用C写JNI的库, 然后在java中通过native方法来调用。
System.setSecurityManager(SecurityManager s)
System.getSecurityManager(): 设置与取得系统的security class。
3.String, StringBuffer
3.1 基本用法
String可以说是我们最常用的一个类, 熟练掌握它的一些基本用法是很有用的。
String是由一组字符组成的字符串, 下标由0开始。 一旦有必要改变原来的内容, 每个String方法都有返回了一个新的String对象。
char charAt(int index) 返回指定位置的字符。
int compareTo(Object o)
int compareTo(String anotherString)
与另外一个对象进行比较。
int compareToIgnoreCase(String str) 与另一个String进行比较, 不区分大小写
String concat(String str) 连接两字符串, 可以直接用+, 因为Java给String覆盖了+
static String copyValueOf(char[] data)
static String copyValueOf(char[] data, int offset, int count)
将data数组转换至String
boolean endsWith(String suffix) 测试此String是否以suffix结尾。
boolean startsWith(String prefix) 测试此String是否以prefix开头。
boolean equals(Object anObject)
boolean equalsIgnoreCase(String anotherString)
比较两字符串的值。 不相等则返回false
byte[] getBytes() 根据缺省的字符编码将String转换成字节数组。
byte[] getBytes(String enc) 根据指定的编码将String转换万字节数组。
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 拷贝字符至一数组中
int indexOf(int ch) 从字串的起始位置查找字符ch第一次出现的位置
int indexOf(int ch, int fromIndex) 从指定的fromIndex位置向后查找第一次出现ch的位置,
int indexOf(String str)
int indexOf(String str, int fromIndex)
如果不存在ch或str都返回-1
int lastIndexOf(int ch) 从字串的最终位置往前查找第一次出现ch的位置
int lastIndexOf(int ch, int fromIndex) 从指定的位置往前查找第一次出现ch的位置,
int lastIndexOf(String str)
int lastIndexOf(String str, int fromIndex)
如果不存在则返回-1
int length() 该字符串的字符长度(一个全角的汉字长度为1)
String replace(char oldChar, char newChar) 将字符oldChar全部替换为newChar, 返回一个新的字符串。
String substring(int beginIndex) 返回从beginIndex开始的字符串子集
String substring(int beginIndex, int endIndex) 返回从beginIndex至endIndex结束的字符串的子集。 其中endIndex – beginIndex等于子集的字符串长度
char[] toCharArray() 返回该字符串的内部字符数组
String toLowerCase() 转换至小写字母的字符串
String toLowerCase(Locale locale)
String toUpperCase() 转换至大写字母的字符串
String toUpperCase(Locale locale)
String toString() 覆盖了Object的toString方法, 返回本身。
String trim() 将字符串两边的半角空白字符去掉, 如果需要去掉全角的空白字符得要自己写。
static String valueOf(primitive p) 将其它的简单类型的值转换为一个String
StingBuffer是一个可变的字符串,它可以被更改。同时StringBuffer是Thread safe的, 你可以放心的使用, 常用的方法如下:
StringBuffer append(param) 在StringBuffer对象之后追加param(可以为所有的简单类型和Object) 返回追加后的StringBuffer, 与原来的对象是同一份。
char charAt(int index) 返回指定位置index的字符。
StringBuffer delete(int start, int end) 删除指定区域start~end的字符。
StringBuffer deleteCharAt(int index) 删除指定位置index的字符。
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 同String的getChars方法
StringBuffer insert(int offset, boolean b) 在指定位置offset插入param(为所有的简单类型与Object)
int length() 同String的length()
StringBuffer replace(int start, int end, String str) 将指定区域start~end的字符串替换为str
StringBuffer reverse() 反转字符的顺序
void setCharAt(int index, char ch) 设置字符ch至index位置。
String substring(int start)
String substring(int start, int end) 同String的subString
String toString() 返回一个String
大家可能已经注意到很多方法都返回了一个StringBuffer对象, 但返回的这个对象与String的方法返回的String不一样, 返回的StringBuffer对象与被操作的StringBuffer对象是同一份, 而String的方法返回的String则肯定是重新生成的一个String。
3.2性能对比
因为String被设计成一种安全的字符串, 避免了C/C++中的尴尬。因此在内部操作的时候会频繁的进行对象的交换, 因此它的效率不如StringBuffer。 如果需要频繁的进行字符串的增删操作的话最好用StringBuffer。 比如拼SQL文, 写共函。 另: 编绎器对String的+操作进行了一定的优化。
x = "a" + 4 + "c"
会被编绎成
x = new StringBuffer().append("a").append(4).append("c").toString()
但:
x = “a”;
x = x + 4;
x = x + “c”;
则不会被优化。 可以看出如果在一个表达式里面进行String的多次+操作会被优化, 而多个表达式的+操作不会被优化。
3.3技巧
1. 在Servlet2.3与JSP1.1以前画面post到后台的数据是通过ISO88591格式进行编码的, 则当遇到全角日文字的时候, 在后台request得到的数据可能就是乱码, 这个时候就得自己进行编码转换, 通过String.getBytes(String enc)方法得到一个字节流, 然后通过String(byte[] bytes, String enc)这个构造函数得到一个用新的编码生成的字符串. 例如将ISO88591的字符串转换成Shift_JIS的字符串, 方法如下:
public static String convertString(String str) {
if (str == null) { return null; }
try {
byte[] buf = str.getBytes("ISO8859_1");
return new String(buf, "Shift_JIS");
} catch (Exception ex) {ex.printStackTrace();return null; }
}
不过在最新的Servlet2.3与Jsp1.2中可以通过request.setCharacterEncoding来进行设置取值的码制, 不需要自己再做转换。
2.因为Java在计算String的长度是以字符为单位的, 因此一个全角与半角的字符长度是一样的, 但是DB中往往是根据字节来计算长度的, 因此我们在做Check的时候得要判断String的字节长, 可以用以下的方法:
public static String length(String str) {
if (str == null) { return 0; }
return str.getBytes().length;
|
|