博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java注意的一些细节问题
阅读量:5881 次
发布时间:2019-06-19

本文共 11574 字,大约阅读时间需要 38 分钟。

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{        @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
list = new ArrayList
();
  • <? super>实现了泛型的逆变,比如:
List
list = new ArrayList();
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] 却可以。

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

直到今天我看到才清楚,里面提到了一种情况:

  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是什么意思

   

你可能感兴趣的文章
RHLinux特殊权限u+s g+s o+t,rwsrwSrwT,7766
查看>>
6、磁盘与文件系统管理
查看>>
Python字符搜算stsearch include "stringlib/fastsearc
查看>>
IOS开发小记
查看>>
Mrtg,Cacti,Zenoss简单比较
查看>>
git 本地添加远程仓库
查看>>
对浮点数-整型数取绝对值
查看>>
第4课:Spark Streaming的Exactly-One的事务处理和不重复输出彻底掌握
查看>>
java总结文章
查看>>
使用Windows迁移工具迁移2003至2012R2 二、IP迁移
查看>>
自己动手——实现Dustjs中间件
查看>>
勘误表《网络规划设计师考试考点分析与真题详解》
查看>>
Flask 使用小结【Updating】
查看>>
详解 Windows 下 Eclipse CDT 配置 C/C++ 编译环境
查看>>
jQuery实现spliter效果
查看>>
Jquery实现正文部分根据浏览器大小自适应高度
查看>>
启动服务成功后OK对齐显示(函数调用)
查看>>
Powershell AS-HTTP-Activation 無效(咋整?)
查看>>
右击项添加cmd命令窗口
查看>>
Autofs自动挂载服务
查看>>