zoukankan      html  css  js  c++  java
  • java注意的一些细节问题

    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.pluginsorg.eclipse.wst.server.core mp0wtpwebappsHJZGG_BLOGsavePath
      /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{
            @Override
            public 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{
            @Override
            public void fun() {}
        }
        
        public H getHImpl(){
            return new G();
        }
    }
    
    class F implements C.E{
        @Override
        public 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{
        
        @Override
        public 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{
        @Override
        public 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{
        @Override
        public void fun() {
        }
    }
    class C implements A{
        @Override
        public 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{
        @Override
        public void fun() {}
        class D implements B{
            @Override
            public int fun() {
                return 0;
            }
        }
    }

    使用内部类,方式2

    class C{
        class D implements A{
            @Override
            public void fun() {
            }
        }
        
        class E implements B{
            @Override
            public int fun() {
                return 0;
            }
        }
    }

     12.java不能使用范型数组原因

      转自:http://www.cnblogs.com/exmyth/p/4598971.html

    Java 不支持泛型数组。也就是说,

    1. List<String>[] ls = new ArrayList<String>[10];  

    是不支持的,而

    1. List<String>[] ls = new ArrayList[10]  或者 List[] ls = new ArrayList[10] 却可以。

    是我一直不清楚为什么不能够声明泛型的数组,指定类型可以让编译的时候不会出现类型安全的提示。

    直到今天我看到Sun的一篇文档才清楚,里面提到了一种情况:

    1. List<String>[] lsa = new List<String>[10]; // Not really allowed.  
    2. Object o = lsa;  
    3. Object[] oa = (Object[]) o;  
    4. List<Integer> li = new ArrayList<Integer>();  
    5. li.add(new Integer(3));  
    6. oa[1] = li; // Unsound, but passes run time store check  
    7. String s = lsa[1].get(0); // Run-time error: ClassCastException.  

    这种情况下,由于JVM泛型的擦除机制,在运行时JVM是不知道泛型信息的,所以可以给oa[1]赋上一个ArrayList<Integer>而不会出现ArrayStoreException,但是在取出数据的时候却要做一次类型转换,所以就会出现ClassCastException,如果可以进行泛型数组的声明,上面说的这种情况在编译期将不会出现任何的警告和错误,只有在运行时才会出错。而对泛型数组的声明进行限制,对于这样的情况,可以在编译期提示代码有类型安全问题,比没有任何提示要强很多。

    基于以上的原因,Java不支持声明泛型数组,更确切地表达是:数组的类型不可以是类型变量,除非是采用通配符的方式,看下面这个例子:

    1. List<?>[] lsa = new List<?>[10]; // OK, array of unbounded wildcard type.  
    2. Object o = lsa;  
    3. Object[] oa = (Object[]) o;  
    4. List<Integer> li = new ArrayList<Integer>();  
    5. li.add(new Integer(3));  
    6. oa[1] = li; // Correct.  
    7. 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();
        }
        @Override
        public 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

  • 相关阅读:
    [MAC]如何抹掉 Mac 磁盘
    [MAC]出售、赠送或折抵 Mac 前该怎么做
    转载 软件项目计划如何编写举例
    GIT
    AWR实战分析之----direct path read temp
    ASM 磁盘组的的scrip
    巨杉db
    High waits on control file sequential read
    如何减小SQL 的物理读,。
    block size大小
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/5638553.html
Copyright © 2011-2022 走看看