当你想要在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
分享到:
相关推荐
在Java编程语言中,实例化对象是创建类的实例,使其具有...总的来说,Java实例化对象是编程中的基本操作,它涉及到类的构造,内存分配,方法调用等多个核心概念。理解这一过程对于深入学习Java和面向对象编程至关重要。
继承关系:类的实例化顺序 * 执行过程为:启动类是否为继承关系树中的一个,如果是则先执行启动类的所有父类的静态语句块;然后执行启动类的静态语句块static{} -> * 执行启动类的main函数 -> 创建对象的继承树从...
"浅析JSP、JAVASCRIPT及JSP与JAVA组件实例化过程分析" 一、JSP、JAVASCRIPT和JSP与JAVA组件实例化过程分析概述 近十年来,客户端网页脚本语言JAVASCRIPT、动态网页技术JSP和JAVA开发组件经历了长足的发展。在实际...
JSP/Javascript 及 JSP 与 JAVA 组件实例化过程浅析 JSP/Javascript 及 JSP 与 JAVA 组件实例化过程浅析是当今 web 开发中非常重要的技术。JSP 是一种完全与平台无关的开发新技术,集成了极高的运行效率、较短的...
在实例化过程中,JVM将按照代码顺序执行实例初始化块和实例初始化语句,并为实例对象的成员变量分配存储空间。 三、实例化的内存模型 在实例化过程中,JVM将为实例对象的成员变量分配存储空间,并赋予初始值。这个...
java教程 由浅入深详解Java 类的实例化顺序 在子类对象被实例化的过程中,变量、构造方法以及代码块三者的先后顺序为: 1. 父类的静态变量和静态代码块,按代码先后顺序执行 2. 子类的静态变量和静态代码块,按...
在实例化过程中,如果父类的构造器是私有的(private),那么子类无法直接访问,除非在同一包内或者通过内部类的方式。如果父类构造器是受保护的(protected)或默认的(包访问权限),子类在任何地方都可以调用。...
### Java实例化类的方法 在Java编程语言中,类的实例化是创建对象的过程,它为程序中的数据和行为提供了一种封装机制。本文将详细探讨四种常用的Java类实例化方法,并通过示例代码加深理解。 #### 1. 使用`new`...
Java让泛型实例化的方法 Java是一种静态类型语言,它可以在编译时检查类型的正确性,以避免运行时的类型错误。然而,在 Java 中使用泛型时,会出现一个问题:如何实例化泛型对象?在 Java 中,泛型擦除机制使得...
下面是一个简单的Java实例,演示了子类对象的实例化过程: ```java class Person{ String name; int age; public Person() { System.out.println("* 父类构造:1. public Person()"); } } class Student ...
综上所述,Spring Bean的实例化顺序是一个复杂的过程,涉及到配置、依赖关系、注解和接口等多个层面。理解这些机制有助于优化和调试应用程序,确保Bean的正确初始化和协同工作。在实际开发中,应谨慎处理Bean的实例...
Java JDK实例开发宝典是一本全面深入探讨Java开发工具包(Java Development Kit)的实践指南。JDK是Java编程的基础,包含了...在学习过程中,不断实践和总结,结合书中的实例,将有助于成为一名合格的Java开发者。
在给定的代码片段中,我们看到一个更复杂的实例化过程,它涉及到枚举类(`BarcodeFormat`)和条件判断。这段代码来自开源库`com.google.zxing`,用于生成各种类型的条形码。 `encode`方法根据传入的`BarcodeFormat`...
1. **公共构造函数**:Java Bean应提供一个无参数的公共构造函数,以便于实例化。 2. **属性**:Bean通常包含一组私有属性(private fields),这些属性可以通过公共的getter和setter方法进行访问和修改,实现数据的...
"java简单实例程序源代码"这个压缩包包含了一系列章节相关的Java实例源代码,适合初学者和有经验的开发者用来加深对Java语言的理解。以下是这些章节可能涉及的重要知识点的详细解释: 1. **CH11**: 这个章节可能...
实例化类、创建对象、方法调用等是Java的核心。通过实例,你可以看到如何定义一个类,如何在类中封装数据和行为,以及如何通过对象进行交互。 3. **继承与多态**:Java支持单继承和多态,这允许类之间的层次结构和...
Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...
3. **包管理**: Java使用包(package)来组织类和接口,有助于代码的模块化和防止命名冲突。在`MessageProj`中,不同的类可能会被分到不同的包下,如`com.messageproj.user`、`com.messageproj.message`等。 4. **...
这种实现方式是在类被首次请求时才创建单例对象,延迟了初始化过程,从而提高了程序的启动性能。但这种方式有一个问题,即线程不安全。在多线程环境下,可能会创建多个实例。例如: ```java public class Singleton...
通过"Java基础实例大全",你可以按照自己的节奏逐步学习这些概念,先尝试编写代码,遇到困难时再查看答案,这样的过程不仅能加深理解,还能提高解决问题的能力。自学是提升技能的重要途径,这本书籍将是你宝贵的伙伴...