java细节

其它

1. 编码规范

代码的可维护性是评价项目的非常重要的指标之一!其中,代码的编码规范就是最基础的表现!

首先,命名必须规范:

  • 包(package)名必须全部使用小写字母,例如cn.huang.spring.Controller这样的包名就是不对的,其中的Controller子包的首字母不应该大写!

  • 所有的类、接口的首字母必须大写,如果名称由多个单词组成,第2个单词开始,每个单词的首字母也必须是大写的,例如:NullPointerExceptionFileNotFoundExceptionArrayIndexOutOfBoundsException……

  • 所有的属性、方法、局部变量、参数的名称都必须是首字母小写,如果名称由多个单词组成,第2个单词开始,每个单词的首字母也必须是大写的

  • 所有的常量的名称中,每个字母都必须是大写的,如果由多个单词组成,则各单词之间使用下划线分隔,例如:state_ok应该写成STATE_OK

  • 绝大部分的属性应该使用名词,例如:nameage……

  • 绝大部分的方法应该使用动词作为前缀,例如:setNamegetName

  • 不遵守以上命名原则的属性或方法应该是疑问类型的属性或方法,例如:isAlivehasNext,即使用ishas作为前缀

代码的版式也非常重要:

  • 在类中,每个方法之间、属性与方法之间,应该添加1行空白

如果对代码的正确版式不太了解,可以使用Eclipse的Source菜单中的Format指令,使Eclipse来帮助排版!

其它……

2. 请求类型的GET与POST

发出请求

只能通过表单(Form)或Javascript代码发出POST请求,而发出GET请求的方式则更多,除了这2种做法以外,还可以通过改变浏览器的地址栏中的URL来发出GET请求!所以,发GET请求比发POST请求更加简单!

传输特点

GET请求的参数会暴露在URL中,不适合传输较私密的数据,例如密码,并且,受到URL长度的限制,GET请求不适合传递大量的数据,例如发邮件、上传文件都不可以使用GET请求!

POST请求的参数不会暴露在URL中,可以传输任何数据(传输过程没有额外的加密处理),并且,传输数据没有长度限制!

相比之下,POST请求更加有优势,但是,POST请求的发出限制略高,不便于刷新,并且,无法分享页面!

3. 查看项目的错误

如果项目结构(Eclipse的左侧)提示了任何错误,都应该在Problems面板中查看详情,有些错误可能并不体现在某个文件或代码中。

如果Eclipse默认没有显示该面板,可以点击Window菜单中的Show View项打开,如果在Show View下仍没有Problems,可以选择Other项再查找。

4. 切换JDK/JRE版本

移除旧版本

Libraries下,对旧版的JDK/JRE点右键,选择Build Path中的Remove ...选项,即可移除。

添加新版本

对项目名称点右键,选择Build Path中的Configure,在弹出的对话框中,选择Libraries选项卡,然后点击右侧的Add Library按钮,在弹出的新对话框中选择JRE System Library并点击Next,通常在下个界面中第3项即是当前系统安装的JDK/JRE版本!

如果在这个面板中没有所需的JDK/JRE版本,则点击Installed JREs按钮并浏览到本机中安装JDK/JRE的目录进行选择即可。

1. 关于构造方法

每个类都有构造方法,用于确定对象的创建过程,当需要创建对象时,使用例如new Object();这样的语法,就是在调用构造方法。

在编写类的时候,可以不需要显式的编写构造方法,当没有显式的编写时,编译器将自动添加公有的、无参数的构造方法!如果已经显式的编写了任何构造方法,编译器将不会自动添加构造方法!

构造方法也是方法,可以重载。

每次创建对象时,都会默认先调用其父类的构造方法!即:

public class User {
    public User() {
        super(); // 调用其父类的构造方法
    }
}

且:使用super关键字调用父类的构造方法的语句,必须编写在子类的构造方法中,必须是子类构造方法中的第1条有效代码!

抽象类的构造方法不允许直接调用,即不允许使用new语法调用抽象类的构造方法来直接创建抽象类的对象!

通常,会在以下情景中自定义构造方法:

  1. 更便捷的创建对象,会自定义若干个带参数的构造方法,使得创建对象时就可以直接确定某些属性的值;

  2. 需要确定创建对象时,就执行的任务,或确定某些属性的值;

  3. 需要限制创建对象,可能将构造方法的访问权限设置得更加严格!

2. 常用快捷键

  • 代码提示 Alt + /
  • 代码排版 Ctrl + Shift + F / Ctrl + A -> Ctrl + I
  • 上下移动 Alt + 上/下
  • 上下复制 Ctrl + Alt + 上/下
  • 删除代码行 Ctrl + D
  • 重命名 Ctrl + 2, R
  • 导包 Ctrl + Shift + I
  • 整理包 Ctrl + Shift + O
  • 添加/去除注释 Ctrl + /

由于使用的系统不同,可能某些系统上快捷键不同,或会发生冲突,如果无法调整,则应该使用Source菜单中对应的功能。

3. 转发与重定向

转发的本质是客户端只发出了1次请求,而重定向的话,客户端发出了2次请求。

转发是发生在服务端内部的,对于客户端而言,并不知道服务端内部有转发的过程,即使是控制器(无论是SpringMVC中的Controller还是传统的Servlet)转发到了JSP,对于客户端而言,也并不知晓。

在执行转发时,URL是不会发生变化的,而重定向会发生变化!

如果需要将较多的数据进行传递,可以使用转发!而重定向则不适合大量数据的传递,因为重定向对应的是2次请求,而2次请求之间数据并不共享!

如果需要地址栏发生变化,与当前页面显示的内容匹配,则必须使用重定向!

4. 关于响应码

服务端对客户端进行响应时,除了有响应的正文以外,还会有响应代码。常见的响应码:

  • 2xx:正确响应,例如:200、206

  • 3xx:重定向,例如:301、302

  • 4xx:请求错误,例如:400、404、405、406

  • 5xx:服务器内部错误,例如:500

5. 枚举类型

使用enum关键字可以声明枚举类型,例如:

public enum RequestMethod {

    GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE

}

定义枚举的前提是:可以穷举所有可能的值,每个值都不相同,并不关心值本身而只关心它表达的意义。

1. 验证用户提交的数据

在开发规范中,认为凡是用户提交的数据,永远是不可靠的,应该对数据进行有效性验证!

通常,关于数据格式(长度、组成字符)的验证,应该使用正则表达式来验证!

package cn.tedu.spring.util;

/**
 * 字符验证工具类
 * @author adminitartor
 */
public class TextValidator {

    /**
     * 

验证用户名的正则表达式

*

验证规则:

*
    *
  • 必须由4~16字符组成;
  • *
  • 必须由大写字母、小写字母、数字、下划线组成,不允许使用其它字符;
  • *
  • 第1个字符必须是大写或小写字母。
  • *
*/ public static final String REG_EXP_USERNAME = "[a-zA-Z]{1}[a-zA-Z0-9_]{3,15}"; /** * 检查用户名的格式是否正确 * @param username 用户名 * @return 如果用户名符合验证规则,则返回true,否则,返回false * @see #REG_EXP_USERNAME */ public static boolean checkUsername(String username) { if (username == null) { return false; } return username.matches(REG_EXP_USERNAME); } }

2. 关于内存

一个完整的计算机硬件系统应该包括:运算器、控制器、存储器、输入设备、输出设备。

存储器分为内部存储器(内存/主存)和外部存储器(外存/辅存)。

内存只有:主板上的ROM、CPU内部的Cache(高速缓存)、内存条(RAM)。

RAM:Random Access Memory。

通常在开发领域讨论的内存指的都是内存条。

RAM的特性有:

  • 它是唯一一个CPU可以直接访问的硬件;

  • 一旦断电,内存中的所有数据会全部丢失;

  • 正在执行的程序和数据必须在内存中。

3. 关于static

使用static可以修饰类的成员(属性/成员变量、方法、内部类、内部接口)。

它的特性是:唯一、常驻

唯一:假设Person类中存在被static修饰的static int hands = 2;,无论把Personnew多少次,无论使用哪个对象调用hands属性,对应的都是同一个值,所以,被static修饰的成员不归属于任何一个对象,在调用时,应该使用 类名.成员 的语法来调用,而不推荐使用 对象.成员 来调用。

常驻:被static修饰的成员,会在它所在的类的名称第一次出现在运行的代码中时,就会被加载到内存,并且,会持续的一直在内存中,所以,表现出“常驻内存”的特性!所以,被static修饰的成员不可以直接访问非static成员!

由于static成员是唯一的,所以,慎用static修饰属性(成员变量),因为可能存在多线程下的数据安全问题(多个线程、同时、对同一个数据、进行修改,则可能导致线程安全问题)。

由于static成员是常驻的,所以,无论是用于修饰哪种类型的成员,都应该慎用,因为可能过度的消耗内存!

4. 内存泄露/溢出(Leak)

内存泄露的主要原因是:尝试释放某个资源,却无法释放,而该资源将持续占用内存,却又无法被使用!

当垃圾回收机制尝试回收垃圾时,可能发现这些数据仍处于“使用状态”(可能与另一些资源保持了连接等等),则不会把这些数据视为垃圾,也就不会回收这些数据占用的内存空间!而由于程序中已经无法再使用变量操作这些数据了,对于开发者而言,这些数据已经用不着了,所以,就出现了“用不着的数据没有被当作垃圾来回收,反而一直占用内存”的现象!

所以,少量的内存泄露是没有明显的危害,但是,如果积少成多,会导致可用内存越来越少,当少到极点还继续使用,就会导致数据溢出。

解决内存泄露的做法就是:及时释放掉不需要使用的资源,例如流等等,应该及时调用close()方法进行归还或关闭。

另外,关于垃圾回收,JVM中的垃圾回收机制会定期自动清理垃圾数据,无须开发者手动释放数据所占用的内存空间,即使调用System.gc()方法也不能保证垃圾回收机制马上来回收数据!

5. 乱码

字符集相当于一本字典,记录了每个字符与二进制码的对应关系!

a   110 0001

在ASCII码中,记录了英文输入法下的所有字母、数据、标点符号与二进制码的对应关系。

由于1个字节只有8个二进制位,无法表示中文(汉字的字符种类太多),所以,需要使用2个字节,即16个二制位来表达!

常见的支持中文的编码有:UTF-8、GBK、GB2312……,还有一些其它编码是完全不支持中文的,例如:ISO8859-1、latin1……

由于支持中文的编码格式有多种,但是,每种编码的二进制码与汉字的对应关系不一样,所以,如果存和取的时候,使用了不同的编码,就会导致乱码!

所以,解决乱码的答案:使用统一的、支持中文的编码。

在项目中,需要统一编码的位置:存储位置(例如数据库等)、显示位置(例如HTML/JSP页面、终端/控制台等)、传输过程(接收请求时、响应时、连接数据库时)、程序源代码……

5. 拦截器与过滤器

首先,这2个组件的执行切入点不相同,过滤器是执行在所有的Servlet之前的,而拦截器是执行在DispatcherServlet之后、控制器之前的。

过滤器是Java EE体系中的,使用时,需要在web.xml中进行配置,而拦截器是SpringMVC框架中的,使用时,需要在Spring的配置文件中进行配置。

过滤器的过滤规则相对比较简单,只能通过节点配置它的适用范围,而拦截器的过滤规则相对比较灵活,即可以配置多项黑名单,还可以配置多项白名单。

你可能感兴趣的:(Spring)