Java 编程 笔记

1. 方法的 连续调用而没有判断,很容易 抛出NullPointerException等 异常

String infant = session.getAttribute("giant").toString();

session.getAttribute("giant")很可能是null值,再调用toString()会产生空指针异常。

解决方法:
String infant = null;
Object plantation = session.getAttribute("giant");
if (plantation != null) {
   infant = plantation.toString();
}


对于强制转换的情况:
String infant = ((Elephant)session.getAttribute("giant")).eat();

这里除了会出现NullPointerException值外,还有可能出现ClassCastException。

解决方法:
String infant = null;
Object plantation = session.getAttribute("giant");
if (plantation != null && plantation instanceof Elephant) {
    infant = ((Elephant)plantation).eat();
}


2. 通过 try...catch块来控制程序流程是不可取的,对异常的跟踪通常会遍历整个栈。

3. for循环的判断表达式应该简单,而不是复杂或耗时的运算,如果遍历次数很多,会对性能造成影响:

        List<Bean> beans = new ArrayList<Bean>();
        for (int i = 0; i < obj.getPressure().length; i++) {
            Bean bean = new Bean();
            bean.setAccuracy(obj.getAccuracy()[i]);
            bean.setPressure(obj.getPressure()[i]);
            beans.add(bean);
        }


可以优化成:
        for (int i = 0, len = obj.getPressure().length; i < len; i++) {
            Bean bean = new Bean();
            bean.setAccuracy(obj.getAccuracy()[i]);
            bean.setPressure(obj.getPressure()[i]);
            beans.add(bean);
        }

目前很多Java虚拟机都会优化该功能。我们可以使用Sun的server或hotspot模式以及其它jvm实现。

4. String的startsWith(String prefix), prefix是大小写敏感的。

5. 数据库表的主键字段通常是int或者bigint类型,但也有可能是其它类型。假设主键类型声明为varchar,值是由数字组成的,根据int或者bigint来查询是会出问题的:

表Employee
emp_id (varchar) emp_name (varchar)
13103422         Pinnacle
09084323         Commensurate

String empId = "13103422";
Integer id = NumberUtils.toInt(empId); // id = 13103422
Employee emp1 = EmployeeService.getEmployeeById(id); // 可以拿到数据
String empId2 = "09084323";
Integer id2 = NumberUtils.toInt(empId2); // id = 9084323
Employee emp2 = EmployeeService.getEmployeeById(id2); // 拿不到数据


6. StringBuilder或StringBuffer拼接的字符串,获取所有的用toString()方法;获取部分的直接用 substring()方法,这样只创建 一个String实例

StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
	sb.append("candy").append(i).append("|");
}
String retVal = sb.substring(0, sb.length() - 1);


下面获取部分的方式会创建两个String实例:
String str = sb.toString();
String retVal = str.substring(0, str.length() - 1);


7. jar打包和解压

将当前目录下的指定文件夹(包括子文件夹和文件)和文件打包成指定jar文件

jar cvf reconciliate.jar org lib about.html plugin.xml plugin.properties


同上,区别是使用指定的清单文件,而不是创建清单文件
jar cvfm reconciliate.jar META-INF/MANIFEST.MF *


解压指定jar包到当前目录
jar xvf reconciliate.jar


显示指定jar包的文件列表
jar tf .jar


选项:

-c 创建新的jar包
-u 更新已存在的jar包
-t 显示jar包中的文件列表
-x 解压jar包
-v 显示压缩或解压的详细信息
-f 指定jar文件名称
-m 指定清单文件并包含到jar包中
-e 指定jar包的执行入口点
-0 只存储,不压缩
-M 不生成清单文件
-i 生成索引信息
-C 切换到指定的目录,将目录下的指定文件包含到jar包中


8. JDK1.5及以下不支持注解

编译环境为JDK1.5及以下时,在代码上加注解会报错:
public interface Config {
    void set(String key, String value);
}

public class ConfigImpl implements Config {
    @Override
    public void set(String key, String value) {
        
    }
}


9. 服务发布后,运行时 NoSuchFieldErrorNoSuchMethodError错误

jar版本冲突,另一个版本的类先被JVM加载,导致获取其属性或调用其方法时报错。

预防:编码注意包和类名的设置,清晰,简洁,尽量不重复。
解决:移除不同版本的jar,MAVEN工程通过pom.xml文件的[ Exclude Maven Artifact...]菜单;将正确版本的jar包放在classpath其它版本的前面(风险大)。

10. 三层架构: 表现层(MVC), 中间层数据访问层(DAO)

表现层
常用的框架是:SpringMVC,Struts1,2

中间层
粘合表现层和数据访问层,把各种对象放到容器中进行管理,以及业务处理。
中间层可以细分为业务层和服务层,业务层主要是通过调用各种服务来实现复杂的逻辑;服务层提供基本的服务调用,封装了数据操作,可以实现事务。

常用的框架是:Spring, EJB

数据访问层
和数据库打交道,获取以及持久化数据,通常一个方法只操作一次数据,不存在事务性问题。

常用的框架是:Hibernate, iBatis

11. 没有修饰符的构造函数,即为protected的:
public class Mankind {
    Mankind() {} // 和 protected Mankind() {} 效果相同
}


12. 原始类型和包装类型

原始类型如:byte, boolean, char, short, int, long, float, double
对应的包装类型:Byte, Boolean, Character, Short, Integer, Long, Float, Double

原始类型有自己的默认值,如int的默认值为0
包装类型的默认值都是null。

JDK5.0起支持编译器自动装箱(从原始到包装)和拆箱(从包装到原始)。

包装类型为null时,和原始类型比较会报错:
Integer val = null;
if (val != 0) { // val为null, null是特殊的引用类型,无法拆箱和int比较,报空指针异常
}

// 可以写成
if (val != null && val != 0) {
}

// 或者
if (Integer.valueOf(0).equals(val)) { // equals参数可以传null
}

你可能感兴趣的:(java,Note)