1. 大括弧作用域問題
public static void main(String[] args) {{int x;{int x;//編譯錯誤:Duplicate local variable x }} }
2.boolean值的運算
public static void main(String[] args) {if(true && false) {}if(true & false) {}System.out.println(true & false);System.out.println(true ^ false);System.out.println(true | false); }
false
true
true
?
3.continue label 和 break label
public static void main(String[] args) {label:for(int i=0; i<2; ++i){System.out.println("i=" + i);for(int j=0; j<3; ++j){if(j == 1){//continue;//break;//continue label;break label;}System.out.println(" j=" + j);}} }
這個例子中,continue label和break具有同樣的作用。
public static void main(String[] args) {label:for(int k=0; k<2; ++k){System.out.println("k=" + k);for(int i=0; i<2; ++i){System.out.println(" i=" + i);for(int j=0; j<3; ++j){if(j == 1){//break;continue label;}System.out.println(" j=" + j);}}} }
這個例子就更加直觀的看到 continue label實現不一樣的效果!
4.基本類型和對應對象分別做參數的函數重載
class A{public void fun(int x){System.out.println("int 重載");}public void fun(Integer x){System.out.println("Integer 重載");} }public class Main{public static void main(String[] args) {A a = new A();int x = 1;Integer ix = 1;a.fun(x);a.fun(ix);} }
int 重載
Integer 重載
?5.獲取絕對路徑
request.getSession().getServletContext() 獲取的是Servlet容器對象,相當于tomcat容器了。getRealPath("/") 獲取實際路徑,“/”指代項目根目錄,所以代碼返回的是項目在容器中的實際發布運行的根路徑。
ClassLoader類的getResource(String name),getResourceAsStream(String name)等方法,使用相對于當前項目的classpath的相對路徑來查找資源。
?
1.jsp頁面
String path = pageContext.getServletContext().getRealPath("/");
或者 String path = request.getSession().getServletContext().getRealPath("/");
String realPath = path+"/WEB-INF/classes/abc.properties";
2.java 程序
InputStream in = getClass().getClassLoader().getResourceAsStream("abc.properties"); // abc.properties放在webroot/WEB-INF/classes/目錄下
??推薦使用Thread.currentThread().getContextClassLoader().getResource("")來得到當前的classpath的絕對路徑的URI表示法。
prop.load(in);
in.close();
3.只通過Java程序操作資源文件
InputStream in = new FileInputStream("abc.properties"); // 相對路徑,項目下的路徑
OutputStream out = new FileOutputStream("abc.properties");
6.異常鏈
public class Main{public static void test2(){throw new NullPointerException("空指針異常!");}public static void test() throws Exception{try{test2();} catch (Exception e){//throw new Exception("自定義異常!"); //(1)throw new Exception("自定義異常!", e);//(2) }}public static void main(String[] args) {try{test();} catch(Exception e) {StringWriter sw = new StringWriter();PrintWriter pw = new PrintWriter(sw);e.printStackTrace(pw);System.out.println(sw.toString());}} }
注意:(1)和(2)的輸出差別
(1)java.lang.Exception: 自定義異常!at com.hjzgg.Main.test(Main.java:28)at com.hjzgg.Main.main(Main.java:34)(2)java.lang.Exception: 自定義異常!at com.hjzgg.Main.test(Main.java:29)at com.hjzgg.Main.main(Main.java:35) Caused by: java.lang.NullPointerException: 空指針異常!at com.hjzgg.Main.test2(Main.java:21)at com.hjzgg.Main.test(Main.java:26)... 1 more
?7.web中一些地址信息
1).地址欄輸入:http://localhost:8080/HJZGG_BLOG/pictureAction!pictureGroupJspGetAllGroups
System.out.println(ServletActionContext.getServletContext().getRealPath("/savePath"));
System.out.println(ServletActionContext.getRequest().getServletPath());
System.out.println(ServletActionContext.getRequest().getRequestURL());
System.out.println(ServletActionContext.getRequest().getRequestURI());
打印的結果如下:
F:\eclipseEE_workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\HJZGG_BLOG\savePath
/pictureAction!pictureGroupJspGetAllGroups
http://localhost:8080/HJZGG_BLOG/pictureAction!pictureGroupJspGetAllGroups
/HJZGG_BLOG/pictureAction!pictureGroupJspGetAllGroups
2).得到完整的URL請求
訪問:http://localhost:8080/HJZGG_BLOG/pictureAction!pictureGroupJspGetAllGroups
HttpServletRequest request;
String url = null;
url = request.getScheme()+"://" //請求協議 http 或 https
+ request.getServerName() //服務器地址
+ ":"
+ request.getServerPort() //端口號
+ request.getContextPath() //項目名稱
+ request.getServletPath() //請求頁面或其他地址 ,例如:pictureAction!pictureGroupJspGetAllGroups
+ "?" + (request.getQueryString()); //參數
System. out.println(url);
輸出:http://localhost:8080/HJZGG_BLOG/pictureAction!pictureGroupJspGetAllGroups?null
3).得到項目根目錄的URL
HttpServletRequest request = ServletActionContext.getRequest();
String url = null;
url = request.getScheme()+"://" //請求協議 http 或 https
+ request.getServerName() //服務器地址(可以替換成 InetAddress.getLocalHost().getHostAddress())
+ ":"
+ request.getServerPort() //端口號
+ request.getContextPath(); //項目名稱
System. out.println(url);
輸出:http://localhost:8080/HJZGG_BLOG
8.內部類和內嵌口
//如果外部類返回是 private類型的內部類,非此外部類的其他方法不能訪問這個內部類 class A{private class B{public void fun(){}}public B getBInstance(){return new B();}public void invokeBMethod(B b){b.fun();}private int x;public int getX(){return x;} }//內嵌接口, 如果你不想將你的借口暴露給外部,寫成如下方式,否則將內嵌接口定義成 public,或者將接口寫成非內嵌接口的形式 class C{interface E{void gun();}private interface D {void fun();}private class DImpl implements D{@Overridepublic void fun() {}}public D getDImpl(){return new DImpl();}public void invokeDMethod(D d){d.fun();} }//內部鏈接提供給外部 interface H{void fun(); } class I{private class G implements H{@Overridepublic void fun() {}}public H getHImpl(){return new G();} }class F implements C.E{@Overridepublic void gun() {} }public class Main{public static void main(String[] args) {A a = new A();int x = a.getX();//error, The type A.B is not visible//a.getBInstance().fun(); a.invokeBMethod(a.getBInstance());C c = new C();//error, The type A.B is not visible // c.getDImpl().fun(); c.invokeDMethod(c.getDImpl());H h = new I().getHImpl();h.fun();} }
?9.協變類型
java中泛型是不變的,可有時需要實現逆變與協變,怎么辦呢?這時,通配符?
派上了用場:
<? extends>
實現了泛型的協變,比如:
List<? extends Number> list = new ArrayList<Integer>();
<? super>
實現了泛型的逆變,比如:
List<? super Number> list = new ArrayList<Object>();
class Parent{public Parent getSelf(){return new Parent();} }class Child extends Parent{@Overridepublic Child getSelf(){return new Child();} }
在Java1.4及以前,子類方法如果要覆蓋超類的某個方法,必須具有完全相同的方法簽名,包括返回值也必須完全一樣。
Java5.0放寬了這一限制,只要子類方法與超類方法具有相同的方法簽名,或者子類方法的返回值是超類方法的子類型,就可以覆蓋。
注意:"協變返回(covariant return)",僅在subclass(子類)的返回類型是superclass(父類)返回類型的extension(繼承)時才被容許。
10.接口內部的類
interface C{class D{public void fun(){System.out.println("this is D class!");}}D getDInstance(); }class E implements C{@Overridepublic D getDInstance() {return new D();} }
正常情況下,不能再接口內部放置任何代碼,但是嵌套類可以作為接口的一部分。你放到接口中的任何類都自動是public和static的。因為類是static的,只是將嵌套類至于接口的命名空間內,這并不違反接口的規則。你設置可以在內部類中實現外層接口。另外實現該接口的類,都可以使用該接口中的內部嵌套類,如上所示。
11.內部類的一個好處
要求,不使用內部類的情況下,實現下面的兩個接口。
接口
interface A{void fun(); }interface B{int fun(); }
不使用內部類,實現兩個接口
//The return type is incompatible with B.fun() class C implements A, B{@Overridepublic void fun() {} }
class C implements A{@Overridepublic void fun() {} }//The return types are incompatible for the inherited methods B.fun(), C.fun() class D extends C implements B{}
使用內部類,方式1
class C implements A{@Overridepublic void fun() {}class D implements B{@Overridepublic int fun() {return 0;}} }
使用內部類,方式2
class C{class D implements A{@Overridepublic void fun() {}}class E implements B{@Overridepublic int fun() {return 0;}} }
?12.java不能使用范型數組原因
轉自:http://www.cnblogs.com/exmyth/p/4598971.html
Java 不支持泛型數組。也就是說,
- List<String>[]?ls?=?new?ArrayList<String>[10];??
是不支持的,而
- List<String>[]?ls?=?new?ArrayList[10] ?或者?List[]?ls?=?new?ArrayList[10]?卻可以。
是我一直不清楚為什么不能夠聲明泛型的數組,指定類型可以讓編譯的時候不會出現類型安全的提示。
直到今天我看到Sun的一篇文檔才清楚,里面提到了一種情況:
- List<String>[]?lsa?=?new?List<String>[10];?//?Not?really?allowed.??
- Object?o?=?lsa;??
- Object[]?oa?=?(Object[])?o;??
- List<Integer>?li?=?new?ArrayList<Integer>();??
- li.add(new?Integer(3));??
- oa[1]?=?li;?//?Unsound,?but?passes?run?time?store?check??
- String?s?=?lsa[1].get(0);?//?Run-time?error:?ClassCastException. ?
這種情況下,由于JVM泛型的擦除機制,在運行時JVM是不知道泛型信息的,所以可以給oa[1]賦上一個ArrayList<Integer>而不會出現ArrayStoreException,但是在取出數據的時候卻要做一次類型轉換,所以就會出現ClassCastException,如果可以進行泛型數組的聲明,上面說的這種情況在編譯期將不會出現任何的警告和錯誤,只有在運行時才會出錯。而對泛型數組的聲明進行限制,對于這樣的情況,可以在編譯期提示代碼有類型安全問題,比沒有任何提示要強很多。
基于以上的原因,Java不支持聲明泛型數組,更確切地表達是:數組的類型不可以是類型變量,除非是采用通配符的方式,看下面這個例子:
- List<?>[]?lsa?=?new?List<?>[10];?//?OK,?array?of?unbounded?wildcard?type.??
- Object?o?=?lsa;??
- Object[]?oa?=?(Object[])?o;??
- List<Integer>?li?=?new?ArrayList<Integer>();??
- li.add(new?Integer(3));??
- oa[1]?=?li;?//?Correct.??
- String?s?=?(String)?lsa[1].get(0);?//?Run?time?error,?but?cast?is?explicit.??
因為對于通配符的方式,最后取出數據是要做顯式的類型轉換的,所以并不會存在上一個例子的問題。
?13.try..catch..finally中的return
public static int fun(){int x = 1;try{return x;} catch(Exception e){} finally {x = 2;}return x; }public static int fun(){int x = 1;try{return x;} catch(Exception e){} finally {x = 2;return x;} }public static int fun(){int x = 1;try{if(x == 1)throw new Exception("test");} catch(Exception e){return x;} finally {x = 2;return x;} }
輸出 1 ?2 ?1
14.內部類繼承
class Outer{private String s;public Outer(String s){System.out.println("Outer initial :" + s);}public void outFun(){System.out.println("outFun");}class Inner{public void innerFun(){System.out.print("內部類調用外部類中的方法: ");outFun();}} }class InheritInner extends Outer.Inner{public InheritInner(Outer out){out.super();}@Overridepublic void innerFun(){super.innerFun();System.out.println("InheritInner override innerFun");} }public class Main{public static void main(String[] args) {Outer out = new Outer("Outer");InheritInner inheritInner = new InheritInner(out);inheritInner.innerFun();} }
這是在《JAVA編程思想》上看到的一道例題,是關于繼承inner classes(內隱類)的。 先把代碼和書上的一些原話寫出來,如下: 由于inner class的構造函數必須連接到一個reference指向outer class 對象身上,所以 當你繼承inner class時,事情便稍微復雜些。問題出在“指向outer class對象”的那個 神秘reference必須被初始化。但derived class之內不存在可連接的缺省對象,這個問題 的答案是,使用專用語法,明確產生該關聯性: class WithInner { class Inner{} } public class InheritInner extends WithInner.Inner { InheritInner(WithInner wi) { wi.super(); //---這里不懂,wi.super()指的是什么,有什么用? } public static void main(String[] args) { WithInner wi = new WithInner(); InheritInner ii = new InheritInner(wi); } }
?15.java自定義注解類,如何獲取注解,如何反射內部類,this$0是什么意思
? http://www.cnblogs.com/hujunzheng/p/5719611.html