StringBuffer 和StringBuilder中的兩個函數:
- //int indexOf(String str) :返回當前StringBuffer對象中,第一個滿足str子串的位置。
- //int indexOf(String str, int fromIndex) :從fromIndex開始查找,返回第一個滿足str子串的位置。
- StringBuffer sb = new StringBuffer("This is a StringBuffer!");
- System.out.println("sb.indexOf(\"is\") = " + sb.indexOf("is")); //2
- System.out.println("sb.indexOf(\"is\", 4) = " + sb.indexOf("is", 4)); //5
- System.out.println("sb.indexOf(\"is\", 4) = " + sb.indexOf("is", 7)); // -1
- //StringBuffer insert(int offset, String str)
- //在當前StringBuffer對象中插入一個元素,在索引號offset處插入相應的值。
- StringBuffer sf = new StringBuffer("..{..}) public class ESBYSYSInquiryMachineInfoSrvRequest {");
- int classIdx = sf.indexOf("public class ");
- if(classIdx > 0){
- sf.insert(sf.indexOf("{", classIdx), " implements java.io.Serializable");
- }
- System.out.println(sf.toString());
- //..{..}) public class ESBYSYSInquiryMachineInfoSrvRequest implements java.io.Serializable{
2.保留2位小數:
- import java.text.DecimalFormat;
- DecimalFormat df=new DecimalFormat("0.00");
- Double x = 83.3333333333;
- x=Double.parseDouble(df.format(x));
3.group by 和 order by
- ORDER BY 用于對數據按指定的列和方法排序。
- select * from syscolumns order by id asc, colorder desc;
- 指示查詢出的結果 按 id 正序排列, colOrder 逆序排列。
- GROUP BY 用于匯總統計。 HAVING 用途和 WHERE類似,但用于對 GROUP BY 的結果進行過濾。
- select id, count(id) from syscolumns group by id;
- 這條語句以 id 進行匯總,統計出每個不同的 id 出現的個數。
- select id, count(id) from syscolumns group by id having count(1) > 10;
- 這條語句以 id 進行匯總,統計出每個不同的 id 出現的個數,但 having 后的條件指定了只顯示 count(id) 大于 10 的數據。。
- 先Group by ,后 Order by
4.日期
獲取當前時間:
- 1.
- SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd" + " " + "hh:mm:ss");
- String datetime = tempDate.format(new java.util.Date());
- 2.
- Calendar now=Calendar.getInstance();
- String time=now.get(Calendar.YEAR)+"-"+(now.get(Calendar.MONTH)+1)+"-"+now.get(Calendar.DAY_OF_MONTH)+" "+now.get(Calendar.HOUR_OF_DAY)+":"+now.get(Calendar.MINUTE)+":"+now.get(Calendar.SECOND);
- 3.Date curDate= new Date(System.currentTimeMillis());
- SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); //24小時制
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");//12小時制
a.獲取年、月、日:
- String year=String.valueOf(c.get(Calendar.YEAR));
- String month=String.valueOf(c.get(Calendar.MONTH)+1);
- String day=String.valueOf(c.get(Calendar.DAY_OF_MONTH));
b.Calendar和Date的轉化
(1) Calendar轉化為Date
- Calendar cal=Calendar.getInstance();
- Date date=cal.getTime();
(2) Date轉化為Calendar
- Date date=new Date();
- Calendar cal=Calendar.getInstance();
- cal.setTime(date);
c.計算一年中的第幾星期
(1)計算某一天是一年中的第幾星期
- Calendar cal=Calendar.getInstance();
- cal.set(Calendar.YEAR, 2006);
- cal.set(Calendar.MONTH,1);
- cal.set(Calendar.DAY_OF_MONTH, 3);
- int weekno=cal.get(Calendar.WEEK_OF_YEAR);
(2)計算一年中的第幾星期是幾號
- SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
- Calendar cal=Calendar.getInstance();
- cal.set(Calendar.YEAR, 2006);
- cal.set(Calendar.WEEK_OF_YEAR, 1);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- System.out.println(df.format(cal.getTime()));
- 輸出:
- 2006-01-02
d:
1天內(注意為add ):
- Calendar c=Calendar.getInstance();
- c.add(Calendar.DAY_OF_MONTH, -1); //得到前一天的時間
- startDateStr=sf.format(c.getTime());
- endDateStr=sf.format(java.util.Calendar.getInstance().getTime()); 推薦使用這種方法獲取當前時間,不推薦使用new Date()
3天內:
- Calendar c=Calendar.getInstance();
- c.add(Calendar.DAY_OF_MONTH, -3); //得到前3天的時間
- startDateStr=sf.format(c.getTime());
近1月:
- Calendar c=Calendar.getInstance();
- c.add(Calendar.MONTH, -1);
- startDateStr=sf.format(c.getTime());
到當前時間的前幾年的時間:
- Calendar c = Calendar.getInstance();
- c.add(Calendar.YEAR, -5);//得到前5年
- SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- String mDateTime=formatter.format(c.getTime());
- String strStart=mDateTime.substring(0, 16);//2002-10-24 09:30
本月(注意為set ):
- Calendar c=Calendar.getInstance();
- c.set(Calendar.DATE,1); //把日期設為當月第一天
- startDateStr=sf.format(c.getTime());
上月:
- Calendar c2=Calendar.getInstance();
- c2.add(Calendar.MONTH,-1);
- c2.set(Calendar.DATE,1);
- startDateStr=sf.format(c2.getTime());
5.文本域input的不可編輯屬性 disabled 和 readonly 區別
disable 屬性 -- 表示已經失效的輸入域
readonly 屬性 -- 表示只讀(只能看到,不能修改)的輸入域(框)
- <input type="checkbox" value="2" name="fav" disabled="disabled" />
- <input type="text" name="notinput" readonly="readonly" />
- /**是否閏年
- */
- public boolean isLeapYear(int year) {
- return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); }
具體日期操作:
http://www.360doc.com/content/09/0820/17/236102_5085810.shtml
可將選中的代碼拖動到QQ聊天窗口中復制
6.File協議
表示本地文件傳輸協議,File協議主要用于訪問本地計算機中的文件 ,就如同在Windows資源管理器中打開文件一樣。
應用:要使用File協議,基本的格式如下:file:///文件路徑,比如要打開F:盤flash文件夾中的1.swf文件,那么可以在資源管理器或IE地址欄中鍵入:file:///f:/flash/1.swf并回車。
3個斜杠代表本地
8.substring(int beginIndex, int endIndex)
該子字符串從指定的 beginIndex 處開始,直到索引 endIndex - 1 處的字符。因此,該子字符串的長度為 endIndex-beginIndex。
示例:
"hamburger".substring(4, 8) returns "urge"
"smiles".substring(1, 5) returns "mile "
參數:
beginIndex - 起始索引(包括)。
endIndex - 結束索引(不包括) 。
9.什么時候用Thread.getContextClassLoader()
需要動態加載很多類和資源的時候 .
通常當你需要動態加載資源的時候 , 你至少有三個 ClassLoader 可以選擇 :
² 系統類加載器或叫作應用類加載器 (system classloader or application classloader)
² 當前類加載器
² 當前線程類加載器
10.instanceof 運算符
指出對象是否是特定類的一個實例。
- String s = "I AM an Object!";
- boolean isObject = s instanceof Object;
- public double calculate(Bill bill) {
- if (bill instanceof PhoneBill) {
- //計算電話賬單
- }
- }
11、java環境配置(都放下面):
CLASSPATH .;%JAVA_HOME%\lib
JAVA_HOME C:\Program Files\Java\jdk1.6.0_22
Path .;%JAVA_HOME%\bin
13.JDK1.5的新特性
“JDK1.5”(開發代號猛虎)的一個重要主題就是通過新增一些特性來簡化開發 ,這些特性包括泛型,for-each循環,自動裝包/拆包,枚舉,可變參數, 靜態導入 。使用這些特性有助于我們編寫更加清晰,精悍,安全的代碼。
自動裝包/拆包
自動裝包/拆包大大方便了基本類型數據和它們包裝類地使用。
自動裝包:基本類型自動轉為包裝類.(int >> Integer)
自動拆包:包裝類自動轉為基本類型.(Integer >> int)
在JDK1.5之前,我們總是對集合不能存放基本類型而耿耿于懷,現在自動轉換機制解決了我們的問題。
在實際開發過程中,我們經常會遇到需要使用對象,而不是內置數據類型的情形。為了解決這個問題,Java語言為每一個內置數據類型提供了對應的包裝類。
所有的包裝類(Integer、Long、Byte、Double、Float、Short)都是抽象類Number的子類。
這里Integer先自動轉換為int進行加法運算,然后int再次轉換為Integer.
- int a = 3;
- Collection c = new ArrayList();
- c.add(a);//自動轉換成Integer.
- Integer b = new Integer(2);
- c.add(b + 2);
枚舉:
- public enum Color
- {
- Red,
- White,
- Blue
- }
然后可以這樣來使用Color myColor = Color.Red.
枚舉類型還提供了兩個有用的靜態方法values()和valueOf(). 我們可以很方便地使用它們,例如
- for (Color c : Color.values())
- System.out.println(c);
帶構造函數的枚舉:
- public enum Color {
- RED("紅色"),BLUE("藍色"),GREEN("綠色");
- private final String name;
- public String getName() {
- return name;
- }
- private Color(String name){
- this.name=name;
- }
- }
- System.out.println("Color.RED.name():"+Color.RED.name()); //RED
- System.out.println("Color.RED.toString():"+Color.RED.toString()); //RED
- System.out.println(Color.RED.getName()); //紅色
Color.RED.name()
Color.RED.toString(); 得到的都是RED
而且這些枚舉值都是public static final的,也就是我們經常所定義的常量,因此枚舉類中的枚舉值最好全部大寫 。
2、即然枚舉類是class,當然在枚舉類型中有構造器,方法和數據域。但是,枚舉類的構造器有很大的不同:
(1) 構造函數只是在構造枚舉值的時候被調用。
(2) 枚舉構造函數只能私有private ,絕對不允許有public構造器。這樣可以保證外部代碼無法新構造枚舉類的實例。因為我們知道枚舉值是public static final的常量而已 但枚舉類的方法和數據域可以允許外部訪問。
- /**
- *
- * 服務器類型
- *
- */
- public enum ServerType {
- JBoss("server/default/deploy","client,common"), WebLogic("",""), GlassFish("","");
- private String deployPath;
- private String libClassPath;
- private ServerType(String deployPath, String libClassPath){
- this.deployPath = deployPath;
- this.libClassPath = libClassPath;
- }
- public String getDeployPath(){
- return this.deployPath;
- }
- public String getLibClassPath(){
- return this.libClassPath;
- }
- }
ServerType serverType = ServerType.JBoss;
String deployPath = serverType.getDeployPath();
String libClassPath = serverType.getLibClassPath();
可變參數:
當不能確定一個方法的入口參數的個數時,以往版本的Java中,通常的做法是將多個參數放在一個數組或者對象集合中作為參數來傳遞,1.5版本以前的寫法是:
- int sum(Integer[] numbers)
- {
- int nSum = 0;
- for(int i: numbers)
- nSum += i;
- return nSum;
- }
在別處調用該方法
sum(new Integer[] {12,13,20});
而在1.5版本中可以寫為:
- public static int sum(Integer... number){
- int nSum=0;
- for(int i : number){
- nSum+=i;
- }
- return nSum;
- }
在別處調用該方法
- System.out.println("sum():"+sum(12,13,14));
- System.out.println("sum():"+sum(12,13));
靜態導入:
要使用靜態成員(方法和變量)我們必須給出提供這個方法的類。使用靜態導入可以使被導入類的所有靜態變量和靜態方法在當前類直接可見,使用這些靜態成員無需再給出他們的類名。
不過,過度使用這個特性也會一定程度上降低代碼地可讀性。
- import static java.lang.Math.*;
- …….
- r = sin(PI * 2); //無需再寫r = Math.sin(Math.PI);
14.o1.CompareTo(o2);
整形間比較會返回1、-1、0
如:
- public static void main(String[] args) {
- //Integer num1;
- //num1 = new Integer("24");
- //Integer num2;
- //num2 = new Integer("34");
- Integer num2=12; //不可使用 int num2=12;因compareTo(T t)中的T是類,所以必須用包裝類
- Integer num1=11;
- System.out.println(num2.compareTo(num1));
- //1 System.out.println("------------------");
- System.out.println(num1.compareTo(num2));
- //-1 }
字符串間比較:
"abcd" .compareTo( "adef" )== -2
"abc" .compareTo( "abcdef" )== -3
"abc" .compareTo( "abc" ) == 0
簡單 字符串的排序 。(例如使用 compareTo 進行姓名的排序)
- //需要進行排序的字符串
- String[] array = new String[] { "lilei", "libai", "james", "poly",
- "wobfei" };
- //使用簡單的循環排序
- for (int i = 0; i < array.length ; i++) {
- for (int j = i + 1; j < array.length-1; j++) {
- if (array[i].compareTo(array[j]) > 0) {
- String temp = array[i];
- array[i] = array[j];
- array[j] = temp;
- }
- }
- }
使用上面針對 String 的排序以后,字符串的內容將會是:
james libai lilei poly wobfei
該例子來源(稍作了修改):http://wobfei.iteye.com/blog/743123
15.編碼習慣
add、saveAdd
edit、saveEdit
16、Math.round();
Math.round(m) = (int)Math.floor(a + 0.5f)
Math.ceil(x):比x大的最小值。
Math.round(x):四舍五入。
Math.floor(x):比x小的最大值。
jdk說得很明白了,
-11.5+0.5=-11 Math.floor(-11)=-11
-11.3+0.5=-10.8 Math.floor(-10.8)= -11
-11.8+0.5=-11.3 Math.floor(-11.3)= -12
17、重寫
關于重寫,遵循以下的規則:
(1)重寫方法必須和被重寫方法具有相同的參數列表, 返回類型必須和被重寫方法的返回類型相同或者是返回類型的子類型 。
(2)重寫方法的訪問控制修飾符不能比被重寫方法更嚴格(比如一個在父類中聲明為public的方法重寫成一個protected的方法)。
18.
- class Test {
- void test(int i) {
- System.out.println("I am an int." + i);
- }
- void test(String s) {
- System.out.println("I am a string.");
- }
- public static void main(String args[]) {
- Test t = new Test();
- char ch = 'y';
- t.test(ch);
- }
- //結果為:I am an int.121
- }
19.JDBC的主要任務是什么?(三個)
1、建立與數據庫的連接。
2、向數據庫發起查詢請求。
3、處理數據庫返回結果。
20.TreeSet的構造函數
TreeSet();
TreeSet(Collection c);//構造一個包含指定 collection 元素的新 TreeSet,它按照其元素的自然順序 進行排序。
TreeSet(Comparator comparator);//構造一個新的空 TreeSet,它根據指定比較器進行排序。
- public class NameComparator implements Comparator<Name>{
- public int compare(Name n1,Name n2){
- if(n1.getName().compareTo(n2.getName())>0) return -1;
- if(n1.getName().compareTo(n2.getName())<0) return 1;
- return 0;
- }
- public static void main(String[] args) {
- Set<Name> set = new TreeSet<Name>(new NameComparator());
- Name n1 = new Name("ray");
- Name n2 = new Name("tom");
- Name n3 = new Name("jame");
- set.add(n1);
- set.add(n2);
- set.add(n3);
- Iterator it = set.iterator();
- while(it.hasNext()){
- Name s = (Name)it.next();
- System.out.print(s.getName()+",");
- }
- System.out.println("一共有對象:"+set.size()+"個");
- }
- }//打印結果是:tom,ray,jame,一共有對象:3個
客戶端排序時因為java.util.Comparator<Type>接口提供了具體的排序方式,<Type>指定了被比較對象的類型,Comparator有個compare(Type x,Type y)的方法,用于比較兩個對象的大小。
21.Object中的hashcode()和equals()
在Java中任何一個對象都具備equals(Object obj)和hashcode()這兩個方法,因為他們是在Object類中定義的。
equals(Object obj)方法用來判斷兩個對象是否“相同”,如果“相同”則返回true,否則返回false。
hashcode()方法返回一個int數,在Object類中的默認實現是“將該對象的內部地址轉換成一個整數返回”。
接下來有兩個個關于這兩個方法的重要規范(我只是抽取了最重要的兩個,其實不止兩個):
規范1: 若重寫equals(Object obj)方法,有必要重寫hashcode()方法,確保通過equals(Object obj)方法判斷結果為true的兩個對象具備相等的hashcode()返回值。說得簡單點就是:“如果兩個對象相同,那么他們的hashcode應該 相等”。不過請注意:這個只是規范,如果你非要寫一個類讓equals(Object obj)返回true而hashcode()返回兩個不相等的值,編譯和運行都是不會報錯的。不過這樣違反了Java規范,程序也就埋下了BUG。
規范2: 如果equals(Object obj)返回false,即兩個對象“不相同”,并不要求對這兩個對象調用hashcode()方法得到兩個不相同的數。說的簡單點就是:“如果兩個對象不相同,他們的hashcode可能相同”。
根據這兩個規范,可以得到如下推論:
1、如果兩個對象equals,Java運行時環境會認為他們的hashcode一定相等 。
2、如果兩個對象不equals,他們的hashcode有可能 相等。
3、如果兩個對象hashcode相等,他們不一定 equals。
4、如果兩個對象hashcode不相等,他們一定不 equals。
http://www.iteye.com/topic/800929
22.序列化
Serializable接口沒有需要實現的方法,
implements Serializable只是為了標注該對象是可被序列化的,
然后 使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStream(對象流)對象 ,接著,使用ObjectOutputStream對象的writeObject(Object obj)方法就可以將參數為obj的對象寫出(即保存其狀態),要恢復的話則用輸入流。
實現序列化(保存到一個文件)的步驟
a)Make a FileOutputStream
FileOutputStream fs = new FileOutputStream("foo.ser");
b)Make a ObjectOutputStream
ObjectOutputStream os = new ObjectOutputStream(fs);
c)write the object
os.writeObject(myObject1);
o s.writeObject(myObject2);
os.writeObject(myObject3);
d) close the ObjectOutputStream
os.close();
23、計劃任務:
java.util.Timer
timer.schedule(...);
http://www.blogjava.net/georgehill/archive/2005/06/09/5793.aspx
http://www.klstudio.com/post/187.html
24.Split
在java.lang包中有String.split()方法,返回是一個數組
我在應用中用到一些,給大家總結一下,僅供大家參考:
1、如果用“.”作為分隔的話,必須是如下寫法:String.split("\\."),這樣才能正確的分隔開,不能用String.split(".");
2、如果用“|”作為分隔的話,必須是如下寫法:String.split("\\|"),這樣才能正確的分隔開,不能用String.split("|");
“.”和“|”都是轉義字符,必須得加"\\";
3、如果在一個字符串中有多個分隔符,可以用“|”作為連字符,比如:“acount=? and uu =? or n=?”,把三個都分隔出來,可以用String.split("and|or");
java轉義字符
\":雙引號
\':單引號
\\:反斜線
25.作用范圍:
this.context.setAttribute(MyConstants.CONTINENTS_KEY, continentlist);
public static final String CONTINENTS_KEY="CONTINENTS";
jsp頁面中可以直接使用 CONTINENTS(${CONTINENTS }) ,而無需context.getAttribute("");
- <body>
- <% request.setAttribute("name","xiaoming") ;%>
- <input type="text" value="${name}"/>
- </body>
26.數組轉為list
- List stooges = Arrays.asList("Larry", "Moe", "Curly");
此時stooges中有有三個元素。注意:此時的list不能進行add操作,否則會報 “java.lang.UnsupportedOperationException”,Arrays.asList()返回的是List,而且是一個定長的List,所以不能轉換為ArrayList,只能轉換為AbstractList
原因在于asList()方法返回的是某個數組的列表形式,返回的列表只是數組的另一個視圖,而數組本身并沒有消失,對列表的任何操作最終都反映在數組上. 所以不支持remove,add方法的
- String[] arr = {"1", "2"};
- List list = Arrays.asList(arr);
其他方式:
- String[] strArray = new String[] { "aa", "bb" };
- List<String> list = new ArrayList<String>(Arrays.asList(strArray));
- list.add("cc");
- System.out.println(list);
結果:[aa, bb, cc]
27、使用ResourceBundle讀取properties文件
有時候有些簡單的配置文件可以沒必要使用xml,其實ResourceBundle類就已經做的很好的。它甚至可以搜索到classpath里的jar文件中一些properties文件。
例如在jar文件中的根目錄放置一個文件:test.properties,然后只要這個jar文件在classpath里。就可以使用這樣的語句來獲得一些屬性:
- ResourceBundle rb = ResourceBundle.getBundle("test");
- String s = rb.getString("FirstKey");
- System.out.println(s);
28、HttpClient學習
- public class TestHttpClient {
- public static void main(String[] args) {
- String url = "http://images.gta-travel.com/HH/Images/HX/HKGA/HKGA-REG-1.jpg|http://images.gta-travel.com/HH/Images/HX/HKGA/HKGA-REG-2.jpg";
- String[] urlArr = url.split("\\|");
- String fileName = "D:\\httpClient";
- HttpClient client = new HttpClient();
- GetMethod method = new GetMethod(urlArr[1]);
- // 使用 GET 方法 ,如果服務器需要通過 HTTPS 連接,那只需要將下面 URL 中的 http 換成 https
- FileOutputStream output = null;
- try {
- client.executeMethod(method);
- File showFile = new File(fileName + ".jpg");
- output = new FileOutputStream(showFile);
- output.write(method.getResponseBody()); //method.getResponseBody()為byte[]類型
- output.flush();
- } catch (HttpException e) {
- } catch (IOException e) {
- } finally {
- if (output != null) {
- try {
- output.close();
- output = null;
- } catch (IOException e) {
- }
- }
- }
- }
- }
http://www.blogjava.net/Alpha/archive/2007/01/22/95216.html
29、棧、堆
1.寄存器:最快的存儲區, 由編譯器根據需求進行分配,我們在程序中無法控制.
2. 棧:存放基本類型的變量數據和對象的引用,但對象本身不存放在棧中,而是存放在堆(new 出來的對象)或者常量池中(字符串常量對象存放在常量池中。)
3. 堆:存放所有new出來的對象。
4. 靜態域 :存放靜態成員(static定義的)
5. 常量池 :存放字符串常量和基本類型常量(public static final)。
6. 非RAM存儲:硬盤等永久存儲空間
這里我們主要關心棧,堆和常量池,對于 棧和常量池中的對象可以共享,對于堆中的對象不可以共享。棧中的數據大小和生命周期是可以確定的,當沒有引用指向數據時,這個數據就會消失。堆中的對象的由垃圾回收器負責回收,因此大小和生命周期不需要確定 ,具有很大的靈活性。
對于字符串:其對象的引用都是存儲在棧中的,如果是 編譯期已經創建好(直接用雙引號定義的)的就存儲在常量池中,如果是運行期(new出來的)才能確定的就存儲在堆中 。對于equals相等的字符串,在常量池中永遠只有一份,在堆中有多份。
new String("China");
對于通過new產生一個字符串(假設為”china”)時,會先去常量池中查找是否已經有了”china”對象,如果沒有則在常量池中創建一個此字符串對象,然后堆中再創建一個常量池中此”china”對象的拷貝對象。這也就是有道面試題:String s = new String(“xyz”);產生幾個對象?一個或兩個,如果常量池中原來沒有”xyz”,就是兩個。
對于成員變量和局部變量:成員變量就是方法外部,類的內部定義的變量;局部變量就是方法或語句塊內部定義的變量。局部變量必須初始化。
形式參數是局部變量,局部變量的數據存在于棧內存中 。棧內存中的局部變量隨著方法的消失而消失。
成員變量存儲在堆中的對象里面 ,由垃圾回收器負責回收
http://www.iteye.com/topic/634530
30.try-catch
- public class Test {
- public static void main(String[] args) {
- System.out.println("return value of getValue(): " + getValue());
- }
- public static int getValue() {
- int i = 1;
- try {
- return i;
- } finally {
- System.out.println("i : finally");
- ++i;
- }
- }
- }
- public static boolean get() {
- try {
- return false;
- } finally {
- return true;
- }
- }
在try中的return真正返回之前 ,會將false保存到一個臨時變量(假設為var)中 ,然后執行finally,在執行finally子句的任何語句之前,會將var中的值取出,如果finally中沒有拋出異常或return、break、continue等語句,則在finally執行完后返回var (相當于返回去完成try中return的執行),如果finally中有return,var值會被覆蓋 ,返回結果是finllay子句中 return的值,如果是異常或break、continue等則執行相應的操作而不是返回。更詳細解釋參考JVM規范或《深入理解JAVA虛擬機(第二版)》。
其實相當于值傳遞
結果:1 true
31、返回一個n位隨機數
random.nextInt(n)
返回0~n 間的整數,包括0,不包括n
- public static String getRandStr(int n){
- Random random = new Random();
- String sRand = "";
- for (int i = 0; i < n; i++) {
- String rand = String.valueOf(random.nextInt(10));
- sRand += rand;
- }
- return sRand;
- }
getRandStr(4)可返回一個4為數
32、java中的main方法
String args[]保存的是 JAVA運行時傳遞給所運行類的參數,你這個類需要參數就傳,不需要就不傳.
- public class TestMain{
- public static void main(String args[]){
- for(int i=0;i<args.length;i++){
- System.out.println(args[i]);
- }
- }
- }
接著用java TestMain first second運行
結果:
first
second
args實際上是個變量。它用來存儲你用命令后執行.class文件時后面跟的參數。args是可以變的,你可以變為你喜歡的任意標識符。
普通方法其實可以不給,只是你在設計方法的時候要給一個不傳參數的方法。
注意:
1、其返回類型應該為void
2、必須為公共方法
a. public static void main()
b. public static void main(String[] string)
c. public static void main(string args)
d. static public int main(String[] args)
e.static void main(String[] args)
33、Map遍歷
- for(Map.Entry<String, String> entry : map.entrySet()){
- System.out.println(entry.getKey()+"--->"+entry.getValue());
- }
34、for循環
for語句的格式為:
for (初始化語句; 條件語句; 控制語句)
{
語句1 ;
語句2 ;
....
語句n ;
}
for 語句的執行順序是:首先執行“初始化語句”;然后測試“條件語句”;若條件成立,則執行語句1到語句n;然后執行“控制”語句;接著再測試條件語句是否成立,如果成立則重復執行以上過程,直至條件不成立時才結束for循環。
35、 Java 內存模型
2.1 Java 內存模型的基本原理
Java 內存模型,由于 Java 被設計為跨平臺的語言,在內存管理上,顯然也要有一個統一的 模型。系統存在一個主內存 (Main Memory) , Java 中所有變量都儲存在主存中,對于所有線程都是共享的。每條線程都有自己的工作內存 (Working Memory) ,工作內存中保存的是主存中某些變量的拷貝,線程對所有變量的操作都是在工作內存中進行,線程之間無法相互直接訪問,變量傳遞均需要通過主存完成。
因為當線程處于不同的cpu中時,它各自的變量保存在各自cpu的寄存器或者高速緩存中,這樣回事的變量對于其它線程暫時不可見。
2.2 Volatile 的內存工作原理
Volatile 是保證多個線程之間變量可見性的,也就是說一個線程對變量進行了寫操作,另外一個線程能夠獲取它最新的值。
它的工作原理是,它對寫和讀都是直接操作工作主存的。(這個可以通過操作字節碼看到)
2.3 Synchronized 的內存操作模型 :
Synchronized, 有兩層語義,一個是互斥,一個是可見性。在可見性上面,它的工作原理有點不同:當線程進入同步塊時,會從主存里面獲取最新值,然后當線程離開同步塊時,再把變量的值更新到主存。
http://tomyz0223.iteye.com/blog/1001778
36.刪除一個文件夾內的所有文件和文件夾
- File file = new File(imgPath);
- if (!file.exists()) return;
- deleteDirectory(file);
- public void deleteDirectory(File path) {
- if( path.exists() ) {
- File[] files = path.listFiles();
- for(int i=0; i<files.length; i++) {
- if(files[i].isDirectory()) {
- deleteDirectory(files[i]);
- }
- else {
- files[i].delete();
- }
- }
- }
- }
37、關于JSP中的pageContext:
使用pageContext所設定的屬性對象,其共享范圍限于同一個JSP頁面,
使用request所設定的屬性對象,其在同一個request處理期間可以共享(包括forward給其它JSP頁面),
session對象所設定的屬性對象則限于同一個進程作用期間可以共享,
而application對象所設定的屬性,則在整個Web應用程序中的JSP頁面都可以共享。
38,Final的初始化
1. final修飾的成員變量沒有默認值
2. final初始化可以在三個地方
(1)聲明的時候初始化
(2)構造函數里初始化
(3)要是沒有static修飾的話可以在非靜態塊里初始化,要是有static修飾的話可以在靜態塊里初始化
3. 使用final成員前要確保已經初始化,如果沒初始化,或者初始化多次,則無法通過編譯。
39、一些轉換技巧
- Map<String, HandlerMapping> matchingBeans =
- BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
- //map轉換list
- List<HandlerMapping> handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
- //map判斷空
- if (!matchingBeans.isEmpty())
- //數組轉List (interceptors 數組)
- interceptorList.addAll(Arrays.asList(this.interceptors));
- //List轉指定對象數組
- interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);
40、java.lang.Number是所有基礎類型的父類
- public abstract class Number implements java.io.Serializable {
- public abstract int intValue();
- public abstract long longValue();
- public abstract float floatValue();
- public abstract double doubleValue();
- public byte byteValue() {
- return (byte)intValue();
- }
- public short shortValue() {
- return (short)intValue();
- }
- }
- public final class Long extends Number implements Comparable<Long>
- public final class Integer extends Number implements Comparable<Integer>
41、JDK、JRE、JVM
JDK:Java Development ToolKit
Java開發工具包
JRE:Java Runtime Environment
Java運行環境
JVM:Java Virtual Machine
Java虛擬機
JDK是SUN公司發布的用于開發Java程序的工具包
在它的bin目錄下有很多工具,常見的包括:javac.exe,java.exe,javadoc.exe等(其中有很多都是用Java編寫的)各種版本的IDE工具也是需要使用JDK來完成編譯,打包,運行等各種功能的。
JRE顧名思義,java的運行環境
JDK是開發工具,在它的安裝目錄下包含了JRE目錄,其實在安裝JDK時(1.4版本以上),有一個安裝選項,如果勾上時,在Java的安裝目錄下會多一個JRE目錄,這里的JRE與JDK下的JRE目錄基本上是完全一致的,那么為什么需要兩個JRE呢?
前面已經提到過,JDK的bin目錄下的很多工具都是用Java編寫的,使用這些工具的時候也是需要運行環境的,通過這些.exe包裝器(這些包裝器提供了尋找tools.jar中的一些java類的快捷方法,不需要輸入一長串的包名和類名)來使用那些工具時,java會自動尋找父目錄下的JRE,所以在這里放置了JRE。
JVM:Java虛擬機,在window下作為動態連接庫(jvm.dll)存在,用于解釋執行Java字節碼。
可以把它理解成是專門用來執行Java程序的一臺機器。也就是說JVM提供了Java執行的硬件平臺。JVM上執行的代碼都存放在.CLASS文件中。JVM只執行字節碼文件。
42、finalize()
Java 技術允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。
這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作。
finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的。
垃圾收集器只知道釋放那些由new分配的內存,所以不知道如何釋放對象的“特殊”內存。為解決這個問題
Java提供了一個名為finalize()的方法,它的工作原理應該是這樣的:一旦垃圾收集器準備好釋放對象占用的存儲空間,它首先調用finalize(),而且只有在下一次垃圾收集過程中,才會真正回收對象的內存。
所以如果使用finalize(),就可以在垃圾收集期間進行一些重要的清除或清掃工作(如關閉流等操作)。但JVM(Java虛擬機)不保證此方法總被調用。
43、原子操作AtomicInteger
- public class AtomicLong extends Number
- implements Serializable
J2SE 5.0提供了一組atomic class來幫助我們簡化同步處理。
基本工作原理是使用了同步synchronized的方法實現了對一個long, integer, 對象的增、減、賦值(更新)操作. 比如對于++運算符, AtomicInteger可以將它持有的integer 能夠atomic 地遞增。在需要訪問兩個或兩個以上 atomic變量的程序代碼(或者是對單一的atomic變量執行兩個或兩個以上的操作)通常都需要被synchronize以便兩者的操作能夠被當作是一個atomic的單元。
- addAndGet(long delta)
- //以原子方式將給定值添加到當前值。
- getAndSet() :
- //設置新值,返回舊值.
- compareAndSet(expectedValue, newValue) :
- //如果當前值 == 預期值,則以原子方式將該值設置為給定的更新值
- //如果更新成功,返回true, 否則返回false
- //換句話可以這樣說: 將原子變量設置為新的值, 但是如果從我上次看到的這個變量之后到現在被其他線程修改了(和我期望看到的值不符), 那么更新失敗
- /* 單線程下, compareAndSet返回永遠為true,
- * 多線程下, 在與result進行compare時, counter可能被其他線程set了新值, 這時需要重新再取一遍再比較,
- * 如果還是沒有拿到最新的值, 則一直循環下去, 直到拿到最新的那個值
- */
為了提高性能,AtomicLong等類在實現同步時,沒有用synchronized關鍵字,而是直接使用了最低層(本地c語言實現代碼)來完成的,
因而你是看不到用synchronized關鍵字的.
比如:AtomicLong類中原子操作方法:
public final boolean compareAndSet(long expect, long update) ;
就是直接使用SUN公司低層本地代碼的原子方法(native方法):
public final native boolean compareAndSwapLong(...)來實現的.
44、Object、String類中equals方法的不同
StringBuffer / StringBuilder的equals方法都是繼承的Object方法
String類中對equals方法進行了重寫
Object類的equals方法的實現:
- public boolean equals(Object obj) {
- return (this == obj);
- }
Object中的equals就是用==來比較當前對象和傳入的參數的。
再看看String的equals實現:
- public boolean equals(Object anObject) {
- if (this == anObject) {
- return true;
- }
- if (anObject instanceof String) {
- String anotherString = (String)anObject;
- int n = count;
- if (n == anotherString.count) {
- char v1[] = value;
- char v2[] = anotherString.value;
- int i = offset;
- int j = anotherString.offset;
- while (n-- != 0) {
- if (v1[i++] != v2[j++])
- return false;
- }
- return true;
- }
- }
- return false;
- }
它去比較內容了。
再看StringBuilder,在其源碼里沒有發現equals方法,那么它就繼承了Object的實現,用==來比較傳進來的參數。
我們看到equals是個實例方法(非static),實例方法是可以被子類重寫而去實現自己想要的行為的,因此,不能輕易的說equals就是比較內容的,其行為是特定于實現的。但==確實是比較地址的。因為java中不支持(至少現在不支持)運算符重載,我們不能改變==的含義,其行為是固定死的。
記得下次不要說“==比較地址,equals比較內容”這樣的話了,如果要說,也在前面加上特定的條件,如“如果比較String”,勿斷章取義。
45、不借助中間變量交換元素
- a = a + b
- b = a - b
- a = a - b
46.UUID
UUID(Universally Unique Identifier)
全局唯一標識符
是指在一臺機器上生成的數字,是1.5中新增的一個類,在java.util下,用它可以產生一個號稱全球唯一的ID
按照開放軟件基金會(OSF)制定的標準計算,用到了以太網卡地址、納秒級時間、芯片ID碼和許多可能的數字。
由以下幾部分的組合:當前日期和時間(UUID的第一個部分與時間有關,如果你在生成一個UUID之后,過幾秒又生成一個UUID,則第一個部分不同,其余相同),時鐘序列,全局唯一的IEEE機器識別號(如果有網卡,從網卡獲得,沒有網卡以其他方式獲得),UUID的唯一缺陷在于生成的結果串會比較長。
JDK1.5
如果使用的JDK1.5的話,那么生成UUID變成了一件簡單的事,以為JDK實現了UUID:
java.util.UUID,直接調用即可.
String s = UUID.randomUUID().toString();
UUID是由一個十六位的數字組成,表現出來的形式例如
550E8400-E29B-11D4-A716-446655440000
47、獲取隨機數
法1:
- int num = getRandom(1000);
- public static int getRandom(int num) {
- return (int) Math.round(Math.random() * num);
- }
API:
double java.lang.Math.random()
//Returns a double value greater than or equal to 0.0 and less than 1.0
long java.lang.Math.round(double a)
法2:
- Random random = new Random();
- int num = random.nextInt(50);
API:
int java.util.Random.nextInt(int n)
//Returns a int value between 0 (inclusive) and the specified value (exclusive),
公共方法:
- public static final String allChar = "023456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
- public static final String numberChar = "023456789";
- /*
- * 獲取隨機字符串
- */
- public static String generateString(int length){ //參數為返回隨機數的長度
- StringBuffer sb = new StringBuffer();
- Random random = new Random();
- for (int i = 0; i < length; i++) {
- sb.append(allChar.charAt(random.nextInt(allChar.length())));
- }
- return sb.toString();
- }
- public static String generateNumber(int length){ //參數為返回隨機數的長度
- StringBuffer sb = new StringBuffer();
- Random random = new Random();
- for (int i = 0; i < length; i++) {
- sb.append(numberChar.charAt(random.nextInt(numberChar.length())));
- }
- return sb.toString();
- }
48、request.getParameterMap()
在servlet中GET請求可以通過HttpServletRequest的getRequestURL方法和getQueryString()得到完整的請求路徑和請求所有參數列表,
POST的需要getParameterMap()方法遍歷得到,
不論GET或POST都可以通過getRequestURL+getParameterMap()來得到請求完整路徑
request.getParameterMap()的返回類型是Map類型的對象,也就是符合key-value的對應關系,但這里要注
意的是,value的類型是String[],而不是String.
得到jsp頁面提交的參數很容易,但通過它可以將request中的參數和值變成一個map,以下是將得到的參數和值
打印出來,形成的map結構:map(key,value[]),即:key是String型,value是String型數組。
例如:request中的參數t1=1&t1=2&t2=3
形成的map結構:
key=t1;value[0]=1,value[1]=2
key=t2;value[0]=3
如果直接用map.get("t1"),得到的將是:Ljava.lang.String; value只所以是數組形式,就是防止參數名有相同的
情況。
- public class ParamsUitl {
- public static Map<String, String> getParamsMap(HttpServletRequest request) {
- Map<String,String> params = new HashMap<String,String>();
- Map requestParams = request.getParameterMap();
- for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
- String name = (String) iter.next();
- String[] values = (String[]) requestParams.get(name);
- String valueStr = "";
- for (int i = 0; i < values.length; i++) {
- valueStr = (i == values.length - 1) ? valueStr + values[i]
- : valueStr + values[i] + ",";
- }
- valueStr = new String(valueStr);
- params.put(name, valueStr);
- }
- return params;
- }
- }
49.特殊字符過濾
- private String formatString(String oldStr){
- String regEx="[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?\r\n|\r|\n|\n\r]";
- Pattern p = Pattern.compile(regEx);
- Matcher m = p.matcher(oldStr);
- return m.replaceAll("").trim();
- }
易錯題:
1、
- int j = 0;
- j = j++;
- System.out.println(j);
沒見過此題的人,大部分人可能得到的結果是:1。 然而,運行的結果會令您徹底失望。這是什么原因呢?原來Java編譯器處理后綴++或--時是這么處理的:java的編譯器在遇到j++和j- -的時候會重新為變量運算分配一塊內存空間,以存放原始的值,而在完成了賦值運算之后,將這塊內存釋放掉。即JAVA先將j的值保存到臨時內存空間中,然 后處理++,即原來的j加1,此時原來的j變成1,然后再執行賦值,將內存空間中所存放的原來的值賦回給j,所以j仍然是0。C#和Java的結果是一樣 的。
相反,C/C++不是這么處理的:C中是通過寄存器作中轉先把j的值賦給它本身,再執行++的操作,這樣結果就是1了。
2、
- String a = "abc";
- String b = "abc";
- System.out.println("====>"+ a==b ); //"+"的優先級比"=="高,實際比較的是"====>abc"與abc false
- System.out.println("====>"+ (a==b) ); //true
3、一眼能說出它的結果
- public class MainTest {
- public static void main(String[] args) {
- String s = null;
- s = s+"word";
- System.out.println("hello " +s);
- }
- }
結果:hello nullword
- String s = null;
- //s = s+"word";
- System.out.println("hello " +s);
- //結果:hello null
抽象類中可以有抽象方法和非抽象方法 !
構造方法可以被重載,但不可以被重寫
數組沒有 length() 這個方法,有 length 的屬性。 String 有有 length() 這個方法。
- Scanner scanner = new Scanner(System.in);
- String temp = scanner.nextLine();
- System.out.println("temp=="+temp);
new String(name.getBytes("iso-8859-1"),"utf-8");
其他:
java類成員變量在沒有賦值的時候會賦以默認值,其它局部變量是不能夠享受這種待遇的。
文章列表