1、Java常用API的运用,效率及技巧1。Java面向对象基本概念2。System3.String, StringBuffer4。数值,字符,布尔对象与简单类型的操作5.Class, ClassLoader6。Java IO系统7。Java集合类8。ResourceBundle, Properties9.Exceptions10.JDBC类库11.常用设计模式1.Java面向对象基本概念Java基本上是面向对象的程序设计语言, 除了一些简单类型(primitive)的变量以外,一切都是对象, 程序是对象的组合, 每个对象都有自己的空间, 并且每个对象都有一种类型, 同一类所有对象都能接受相同的消
2、息. 下面只对Java中对象的结构作简单的说明:类(class):class是定义类的关键字,类中包含类变量, 方法, 内部类, 内部接口等。由class可以生成类的实例, 即一个个对象。 如果一个类的成员被定义成static的,则这个成员不专属于任何对象, 而是属于这个类, 所有的对象共享这个成员。抽象类(abstract class):抽象类不能直接生成一个实例, 抽象类中必需有方法是abstract的,抽象类的意思就是它实现了一部分的方法, 而定义为abstract的方法则需要在它的子类中去实现。接口(interface):接口可以理解为纯抽象的类, 它的每个方法都是未实现的, 它可以有
3、成员变量, 但必须是static的.一个类如果从这个接口继承(implements)则它必须实现这个接口的所有方法。继承类用关键字:extends,继承接口用关键字:implements. 一个类只能从一个类继承下来, 但可以从多个接口继承(类似于C+的多重继承)。 子类可以覆盖父类的方法(method), 但不能覆盖父类的成员变量(field)。 如果父类的方法为final或static的则不能被覆盖.类的初始化顺序是, 如果有父类, 则先初始化父类的field,然后执行父类的构造函数, 如果子类没有显式的去调父类的构造函数则缺省的会去调父类的无参数构造函数。 然后是子类的field与构造函
4、数的初始化。public interfaceSuperInterface public staitcString SOME_FLAG = “1”;public voidsomeMethod();public ClassSuperClass System.out。println(“init SuperClass field”);publicSuperClass() System.out。println(“init SuperClass Constructor”); public voidrunMethod() System.out。println(“run SuperClass runMetho
5、d()”); public ClassSubClassextendsSuperClass implementsSuperInterfaceSystem.out.println(“init SubClass field”); publicSubClass() System。out。println(“init SubClass Constructor); public voidsomeMethod() System.out。println(“run SubClass someMethod()”); public voidrunMethod() System。out。println(“run Sub
6、Class runMethod(); 有以下test代码:public classTest public voidmain(String args) SubClass sub =newSubClass();sub。 runMethod();则会输出:init SuperClass fieldinit SuperClass Constructorinit SubClass fieldinit SubClass Constructorrun SubClass runMethod()以下章节所讲述到的常用的Java API就是一些Java自带的一些Class或Interface的用法。2System
7、System类位于package java。lang下面,凡是此package下面的类我们可以直接引用无需先import进来,因为JVM缺省就load了这下面的所有class.System包含了一些我们常用的方法与成员变量。System不能被实例化,所有的方法都可以直接引用.主要作用大致有:输入输出流:(PrintStream) System.out(标准终端输出流),(PrintStream) System。err(标准错误输出流),(InputStream) System。in(标准输入流)。我们还可以重定向这些流,比如将所有的System.out的输出全部重定向至一文件中去。System
8、.setOut(PrintStream)标准输出重定向System。setErr(PrintStream)标准错误输出重定向System.setIn(InputStream)标准输入重定向取当前时间:System。currentTimeMillis()所取到的时间是从1970/01/01以来1/1000秒计算的long型值.这个值可以转换至Date或Timestamp值.它一般还可以用来计算程序执行的时间。例:longbeginTime = System。 currentTimeMillis();System.out.println(“run time = ” + (System. curre
9、ntTimeMillis() beginTime);数组拷贝:System。arraycopy(Objectsrc, intsrc_position,Objectdst, intdst_position, intlength)src: 源数组.src_position: 源数组拷贝的起始位置.dst: 目标数组dst_position: 拷贝至目标数组的起始位置length: 拷贝元素的长度利用System。arraycopy进行数组的拷贝效率是最高的, 一般情况下我们自己很少直接用到这个方法,但在集合类的内部中都大量使用了这个方法。例:int array1 = 1, 2, 3, 4, 5;i
10、nt array2 = 4, 5, 6, 7, 8;int array3 = new int8;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 p
11、rops):设置系统的Properties。System.getProperty(String key): 根据一个键值来取得一个Property.System。setProperty(String key, String value): 设置系统的一个Property。JVM起动的时候将会有一些缺省的Properties值, 例如:java.versionJava运行环境版本java。homeJava主目录installation directoryjava。class。pathJava的class pathjava.ext.dirsJava的扩展目录路径file。separator文件分隔
12、符(”/ 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 libn
13、ame):加载native的动态库。可以用C写JNI的库,然后在java中通过native方法来调用.System.setSecurityManager(SecurityManager s)System.getSecurityManager():设置与取得系统的security class.3String, StringBuffer3。1基本用法String可以说是我们最常用的一个类,熟练掌握它的一些基本用法是很有用的。String是由一组字符组成的字符串,下标由0开始.一旦有必要改变原来的内容,每个String方法都有返回了一个新的String对象。char charAt(int index
14、)返回指定位置的字符。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数组转换至St
15、ringboolean endsWith(String suffix)测试此String是否以suffix结尾.boolean startsWith(String prefix)测试此String是否以prefix开头.boolean equals(Object anObject)boolean equalsIgnoreCase(String anotherString)比较两字符串的值。不相等则返回falsebyte getBytes()根据缺省的字符编码将String转换成字节数组。byte getBytes(String enc)根据指定的编码将String转换万字节数组。void ge
16、tChars(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都返回1int lastIndexOf(int ch)从字串的最终位置往前查找第一次出现ch的位置int lastI
17、ndexOf(int ch, int fromIndex)从指定的位置往前查找第一次出现ch的位置,int lastIndexOf(String str)int lastIndexOf(String str, int fromIndex)如果不存在则返回-1int length()该字符串的字符长度(一个全角的汉字长度为1)String replace(char oldChar, char newChar)将字符oldChar全部替换为newChar,返回一个新的字符串。String substring(int beginIndex)返回从beginIndex开始的字符串子集String su
18、bstring(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方法,返回本
19、身。String trim()将字符串两边的半角空白字符去掉,如果需要去掉全角的空白字符得要自己写。static String valueOf(primitive p)将其它的简单类型的值转换为一个StringStingBuffer是一个可变的字符串,它可以被更改。同时StringBuffer是Thread safe的,你可以放心的使用,常用的方法如下:StringBuffer append(param)在StringBuffer对象之后追加param(可以为所有的简单类型和Object)返回追加后的StringBuffer,与原来的对象是同一份。char charAt(int index)返
20、回指定位置index的字符.StringBuffer delete(int start, int end)删除指定区域startend的字符。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的
21、length()StringBuffer replace(int start, int end, String str)将指定区域startend的字符串替换为strStringBuffer reverse()反转字符的顺序void setCharAt(int index, char ch)设置字符ch至index位置。String substring(int start)String substring(int start, int end)同String的subStringString toString()返回一个String大家可能已经注意到很多方法都返回了一个StringBuffer对
22、象,但返回的这个对象与String的方法返回的String不一样,返回的StringBuffer对象与被操作的StringBuffer对象是同一份,而String的方法返回的String则肯定是重新生成的一个String.3。2性能对比因为String被设计成一种安全的字符串,避免了C/C+中的尴尬。因此在内部操作的时候会频繁的进行对象的交换,因此它的效率不如StringBuffer。如果需要频繁的进行字符串的增删操作的话最好用StringBuffer.比如拼SQL文,写共函。另:编绎器对String的+操作进行了一定的优化.x = ”a” + 4 + c会被编绎成x = new String
23、Buffer().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
24、bytes, String enc)这个构造函数得到一个用新的编码生成的字符串。例如将ISO88591的字符串转换成Shift_JIS的字符串,方法如下:public staticString convertString(String str) if(str = null) returnnull; trybyte buf = str.getBytes(ISO8859_1”);return newString(buf, Shift_JIS”); catch (Exception ex) ex.printStackTrace();returnnull; 不过在最新的Servlet2。3与Jsp1。
25、2中可以通过request。setCharacterEncoding来进行设置取值的码制,不需要自己再做转换.2因为Java在计算String的长度是以字符为单位的,因此一个全角与半角的字符长度是一样的,但是DB中往往是根据字节来计算长度的,因此我们在做Check的时候得要判断String的字节长,可以用以下的方法:public staticString length(String str) if(str = null) return 0; returnstr.getBytes()。length;4数值,字符,布尔对象与简单类型的操作简单的对照表如下:ObjectPrimitive范围Numb
26、erLonglong9223372036854775808 to 9223372036854775807Integerint2147483648 to 2147483647Shortshort-32768 to 32767Bytebyte128 to 127DoubledoubleFloatfloatCharactercharu0000touffffBooleanbooleanfalse and true与C等其它语言不同的是数值的范围不随平台的改变而改变,这就保证了平台之间的统一性,提高了可移植性.Number:Number本身是个抽象类,不能直接使用,所有直接从Number继承下来的子类都
27、有以下几种方法:byte byteValue()返回字节值double doubleValue()返回double值float floatValue()返回float值int intValue()返回float值long longValue()返回long值short shortValue()返回short值在需要通过Object来取得简单数据类型的值的时候就得用到以上的方法,不过我不推荐不同类型之间的取值,比如Long型的Object不要直接去调用intValue(),精度可能会丢失。如果想通过String来得到一个数值类型的简单类型值,一般在每个Number的类里面都有一个parseXXX
28、(String)的静态方法,如下:byte Byte。parseByte(String s)double Double。parseDouble(String s)float Float.parseFloat(String s)int Integer。parseInt(String s)long Long.parseLong(String s)short Short。parseShort(String s)如果想直接从String得到一个Number型的Object,则每个Number类里面都有valueOf(String s)这个静态方法。如:Byte Byte。valueOf(String
29、s)Double Double.valueOf(String s)Float Float。valueOf(String s)Integer Integer。valueOf(String s)Long Long.valueOf(String s)Short Short.valueOf(String s)一般的在构造一个Number的时候都可以通过一个String来完成,比如:Long longObject = new Long(“1234567890”);等价于Long longObject = Long.valueOf(“1234567890”);因为每个Number的子类都实现了Object
30、的toString()方法,所以,如果想得到一个String型的数值,直接调用XXX.toString()就可以了.如果想得到一个简单类型的String,方法很多总结如下:首先生成对应的Number Object类型,然后调用toString()调用Number子类.toString(type t)其中t就是简单类型的数据.调用String。valueOf(type t)(推荐使用这种方法)大家可以看出,往往一种结果可以用多种方法实现,总的原则就是深度最少优先.比如由一个String得到一个简单类型的值可以有以下两种方法:Integer。parseInt(“12345);或(new Integ
31、er(s))。intValue(“12345”);当然应该使用第一种方法。Character:Character对应着char类型,Character类里面有很多静态的方法来对char进行判断操作,详细的操作请参照JDK API。Java对字符的判断操作基本都是以Unicode进行的,比如Character。isDigit(char ch)这个方法,不光半角的09符合要求,全角的日文0-9也是符合要求的。Boolean:Boolean对应着boolean类型,boolean只有true和false两个值,不能与其它数值类型互换,可以通过字符串”true以及”false”来得到Object的Bo
32、olean,也可以通过简单类型的boolean得到Boolean,常用方法如下:Boolean(boolean value)通过简单类型的boolean构造BooleanBoolean(String s)通过String(“true”, “false)构造Booleanboolean booleanValue()由Object的Boolean得到简单类型的boolean值boolean equals(Object obj)覆盖了Object的.equals方法,Object值比较static Boolean valueOf(String s)功能与构造函数Boolean(String s)一样
33、5Class, ClassLoaderJava是一种介于解释与编绎之间的语言,Java代码首先编绎成字节码,在运行的时候再翻译成机器码.这样在运行的时候我们就可以通过Java提供的反射方法(reflect)来得到一个Object的Class的额外信息,灵活性很大,可以简化很多操作。Class:任何一个Object都能通过getClass()这个方法得到它在运行期间的Class。得到这个Class之后可做的事情就多了,比如动态得到它的构造函数,成员变量,方法等等。还可以再生成一份新的实例,下面只给出几个我们常用的方法,更详细的用法参照Java APIClass Class.forName(Str
34、ing className) throws ClassNotFoundException:这是个静态方法,通过一个Class的全称来得到这个Class。String getName()取得这个Class的全称,包括package名.Object newInstance()得到一个实例,调用缺省的构造函数。例如我们有一个类:com。some.util。MyClass如果得到它的一个实例呢?可能有以下两种方法:MyClass myClass = new MyClass(),直接通过操作符new生成;或者:MyClass myClass =(MyClass) Class.forName(“com。s
35、ome.util.MyClass)。newInstance();也许有人就会怀疑第二种方法实际意义,能够直接new出来干嘛绕弯。但实际上它的用处却很大,举个例子:用过struts的人都知道,在actionconfig。xml当中定义了一系列的formBean与actionBean,当然每个form与action都具有同类型,这样在一个request过来的时候我可以动态的生成一个form与action的实例进行具体的操作,但在编码的时候我并不知道具体是何种的form与action,我只调用它们父类的方法。你如果要用第一种方法的话,你得在编码的时候通过一个标志来判断每一次request需要具体生成
36、的form与action,代码的灵活性大大降低。总的来说在面向接口的编程当中经常使用这种方法,比如不同数据库厂家的JDBC Driver都是从标准的JDBC接口继承下去的,我们在写程序的时候用不着管最终是何种的Driver,只有在运行的时候确定。还有XML的Parser也是,我们使用的只是标准的接口,最后到底是谁来实现它的,我们用不着去管.ClassLoader:ClassLoader是一个抽象类,一般的系统有一个缺省的ClassLoader用来装载Class,用ClassLoader。getSystemClassLoader()可以得到。不过有时候为了安全或有其它的特殊需要我们可以自定义自己
37、的ClassLoader来进行loader一些我们需要的Class,比如有的产品它用了自己的ClassLoader可以指定Class只从它指定的特定的JAR文件里面来loader,如果你想通过覆盖ClassPath方法来想让它用你的Class是行不通的。有兴趣的可以参照Java API的更详细的用法说6. Java IO系统JDK1。0输入流InputStreamByteArrayInputStreamFileInputStreamFilterInputStreamObjectInputStreamPipedInputStreamSequenceInputStreamBufferedInput
38、StreamDataInputStreamPushbackInputStreamLineNumberInputStreamJDK1。1输入流ReaderBufferedReaderFilterReaderPipedReaderStringReaderInputStreamReaderCharArrayReaderFileReaderPushbackReaderLineNumberReaderJDK1.0输出流OutputStreamBufferedOutputStreamDataOutputStreamPrintStreamByteArrayOutputStreamFileOutputStre
39、amFilterOutputStreamObjectOutputStreamPipedOutputStreamJDK1。1输出流WriterBufferedWriterFilterWriterPipedWriterStringWriterFileWriterPrintWriterOutputStreamWriterCharArrayWriter如果你刚刚接触Java的IO部分,你可能会感觉无从入手,确实Java提供了过多的类,反而让人感到很乱。可将Java库的IO类分为输入与输出两个部分,在1。0版本中提供了两个抽象基类,所有输入的类都从InputStream继承,所有输出的类都从Output
40、Stream继承,1。1提供了两个新的基类,负责输入的Reader与输出的Writer,但它们并不是用来替换原来老的InputStream与OutputStream,它们主要是让Java能更好的支持国际化的需求。原来老的IO流层只支持8位字节流,不能很好地控制16位Unicode字符。Java内含的char是16位的Unicode,所以添加了Reader和Writer层次以提供对所有IO操作中的Unicode的支持.除此之外新库也对速度进行了优化,可比旧库更快地运行。InputStream的类型:1字节数组2String对象3文件4管道,可以从另外一个输出流得到一个输入流5一系列的其他流,可以
41、将这些流统一收集到单独的一个流内。6其他起源(如socket流等)还有一个是File类,Java中一个目录也是一个文件,可以用file。isFile()和file。isDirectory()来进行判断是文件还是目录。File对象可能作为参数转换为文件流进行操作.具体操作参照Java IO API。常用方法:/*拼文件名,在windows()跟unix(/)上的文件分割符是不一样的可以通过File类的静态成员变量separator取得/public staticString concatFileName(String dir, String fileName) String fullFileNa
42、me = ”;if(dir。endsWith(File.separator) fullFileName = dir + fileName;elsefullFileName = dir + File。separator + fileName;returnfullFileName; /*从控制台读取输入的数据, System.in (InputStream)先转换至InputStreamReader再用 BufferedReader进行读取。*/BufferedReader in =newBufferedReader(new InputStreamReader(System。in));String
43、 str = ”;while(str != null) str = in.readLine();/ process(str); /*从文件中按行进行读取数据处理/BufferedReader in =newBufferedReader(new FileReader(”infilename”);String str;while(str = in.readLine() != null) / process(str); in。close();/*写数据至一个新的文件中去。/BufferedWriter out =newBufferedWriter(new FileWriter(”outfilename”));out.write(a String”);out.close();/
©2010-2024 宁波自信网络信息技术有限公司 版权所有
客服电话:4008-655-100 投诉/维权电话:4009-655-100