`
sweed0
  • 浏览: 6517 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

java类的实例化过程

 
阅读更多

当你想要在java类包中某个层次上添加一个非java文件,像资源文件,XML配置文件

或其他格式文件的时候, Class.getResource() 是一个很有用的方法,它不是根据

绝对路径来定位某个资源(文件),而是根据相对类路径来定位资源。当我们用绝对路径

来定位java类包中某个层次的资源时,项目的部署和迁移可能会出现问题,而且跨平台

运行也会出现问题。(像 "c:/1.txt"这个文件路径 在linux里是不能被识别的)

 

下面显示了一个类层次:

 

+bin--

    +test_1--

        Test.class

        +test_2--

            hello_en.txt

    hello_zh.txt

 

注意: 资源文件必须在编译后类路径里才能通过Class.getResource() 的方式被定位 ,

而不是在源文件路径里。

===

 

下面展示一段代码
String path = getClass().getResource("/").getPath();

String path = getClass().getClassLoader.getResource("").getPath(); 
如果当前路径中包含了空格,则返回的路径字符串空格则被转义为(%20),如何解决这个问题呢?

String path = getClass().getResource("/").toURI().getPath();

String path = getClass().getClassLoader.getResource("").toURI().getPath(); 

也可以   java.net.URLDecoder.decode(path,"UTF-8 ");其他编码也是可以的哈。


到这个地方其实还有两个疑问1.getClass().getResource("/")与getClass().getClassLoader.getResource("/")有什么区别;
2.toURI()是什么;

 

Class().getResource与ClassLoader.getResource

Class().getResource,如果以 “/”开始则查找的路径是以classpath指向的绝对路径,包括jar文件路径,
如果不是以“/”开始,则查找的路径是从当前包路径开始查找,故jar文件查找不到


ClassLoader.getResource,查找的时候不能以“/”开头,查找的路径必须是绝对路径,查找范围包括jar文件


例子:可以在任意包路径下运行,然后根据结果得出以上结论

System.out.println(getClass().getResource(""));
System.out.println(getClass().getResource("/"));
System.out.println(getClass().getClassLoader().getResource(""));
System.out.println(getClass().getClassLoader().getResource("/"));

PS:查看一下Class.getResource源代码,会发现最终都是以ClassLoader.getResource获取资源位置

WEB应用中也可以这样用:
URL url = (URL) ServletActionContext.getServletContext().getResource("/WEB-INF/classes/config/chen wei/jdbc.properties");
// URL url = (URL)req.getSession().getServletContext().getResource("/WEB-INF/webinffile.txt");


URI与URL

ClassLoader.getResource("/").toURI()或Class().getResource("/").toURI()

getResource方法返回的是一个URL对象,toURI()是将RUL对象转换为URI对象.

查看了 URL和URI 对于getPath()方法的源代码,前者是没有对转义字符的解码的过程,而后则是有一个解码的过程
java.net.URLDecoder.decode;


URI与URL区别,我只是简单说说我简单的理解的

URI统一资源标识符,是针对整个资源的一个属性的管理对象,包括了URL

URL统一资源定位符,是对资源的管理,如获取资源文件流等

详细的自己看JDK API,估计看完了你脑壳也昏了

 

==

url转义字符
url转义字符原理

如果表单的action为list.jsf?act=go&state=5

则提交时通过request.getParameter可以分别取得act和state的值。

如果你的本意是act='go&state=5'这个字符串,那么为了在服务端拿到act的准确值,你必须对&进行转义

[预备知识]
 
        对与通过get方式提交的url,浏览器在提交前首先根据http协议把一一个的参数及其值解析配对。而url的参数间是通过&分割的,这就是浏 览器进行参数配置的分割依据。如果你的参数值中含有&等url特殊字符,那么你在服务器端就会拿到意想不到的值。所以必须对url的特殊字符进行 转义。
编码的格式为:%加字符的ASCII码,即一个百分号%,后面跟对应字符的ASCII(16进制)码值。例如 空格的编码值是"%20"。
下表中列出了一些URL特殊符号及编码
 

      十六进制值
1. +  URL 中+号表示空格 %2B
2. 空格 URL中的空格可以用+号或者编码 %20
3. /  分隔目录和子目录 %2F 
4. ?  分隔实际的 URL 和参数 %3F 
5. % 指定特殊字符 %25 
6. # 表示书签 %23 
7. & URL 中指定的参数间的分隔符 %26 
8. = URL 中指定参数的值 %3D

(9.\ 指定为 %5c)

所以上述的action你应该写成list.jsf?act=go%26state=5

====

大家在往参加口试的时候,经常会碰到这样的考题:给你两个类的代码,它们之间是继续的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码 对变量值进行了某种运算,另外还有一些将变量值输出到控制台的代码,然后让我们判定输出的结果。这实际上是在考查我们对于继续情况下类的初始化顺序的了 解。我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是(静态变量、静态初始化块)>(变量、初始化 块)>构造器。我们也可以通过下面的测试代码来验证这一点: Java代码
    public class InitialOrderTest {

        // 静态变量
        public static String staticField = "静态变量";
        // 变量
        public String field = "变量";

        // 静态初始化块
        static {
            System.out.println(staticField);
            System.out.println("静态初始化块");
        }

        // 初始化块
        {
            System.out.println(field);
            System.out.println("初始化块");
        }

        // 构造器
        public InitialOrderTest() {
            System.out.println("构造器");
        }

        public static void main(String[] args) {
            new InitialOrderTest();
        }
    }


    运行以上代码,我们会得到如下的输出结果:
    静态变量
    静态初始化块
    变量
    初始化块
    构造器
    这与上文中说的完全符合。那么对于继续情况下又会怎样呢?我们仍然以一段测试代码来获取终极结果: Java代码
    class Parent {
        // 静态变量
        public static String p_StaticField = "父类--静态变量";
        // 变量
        public String p_Field = "父类--变量";

        // 静态初始化块
        static {
            System.out.println(p_StaticField);
            System.out.println("父类--静态初始化块");
        }

        // 初始化块
        {
            System.out.println(p_Field);
            System.out.println("父类--初始化块");
        }

        // 构造器
        public Parent() {
            System.out.println("父类--构造器");
        }
    }

    public class SubClass extends Parent {
        // 静态变量
        public static String s_StaticField = "子类--静态变量";
        // 变量
        public String s_Field = "子类--变量";
        // 静态初始化块
        static {
            System.out.println(s_StaticField);
            System.out.println("子类--静态初始化块");
        }


// 初始化块
        {
            System.out.println(s_Field);
            System.out.println("子类--初始化块");
        }

        // 构造器
        public SubClass() {
            System.out.println("子类--构造器");
        }

        // 程序进口
        public static void main(String[] args) {
            new SubClass();
        }
    }


     运行一下上面的代码,结果马上呈现在我们的眼前:
    父类--静态变量
    父类--静态初始化块
    子类--静态变量
    子类--静态初始化块
    父类--变量
    父类--初始化块
    父类--构造器
    子类--变量
    子类--初始化块
    子类--构造器
    现在,结果已经不言自明了。大家可能会留意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化 是在父类的变量、初始化块和构造器初始化之前就完成了。那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是 先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。同样, 我们还是写一个类来进行测试: Java代码
    public class TestOrder {
        // 静态变量
        public static TestA a = new TestA();

        // 静态初始化块
        static {
            System.out.println("静态初始化块");
        }

        // 静态变量
        public static TestB b = new TestB();

        public static void main(String[] args) {
            new TestOrder();
        }
    }

    class TestA {
        public TestA() {
            System.out.println("Test--A");
        }
    }

    class TestB {
        public TestB() {
            System.out.println("Test--B");
        }
    }


     运行上面的代码,会得到如下的结果:
    Test--A
    静态初始化块
    Test--B
    大家可以随意改变变量a、变量b以及静态初始化块的前后位置,就会发现输出结果随着它们在类中出现的前后顺序而改变,这就说明静态变量和静态初始化块是依 照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。了解了继续情况下类的初始化顺序之后,如何判定终极输出结果就迎刃而解了。



  一个简单的堆栈溢出例子,在构造方法里面new当前类实例。

// 构造器
    public InitialOrderTest() {
        System.out.println("构造器");
        new InitialOrderTest().doit();
    }

  无穷制的调用,堆栈溢出!

 

=======

内容来源:http://www.csdnjava.com/forum.php?mod=viewthread&tid=28072

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics