项目review--2017.05.27

本文探讨了Java中引用传递的细节,强调了在数据库字段设计、枚举映射、foreach循环健壮性、批量交互及类型选择上的注意事项,并提出了有效的编程建议。

Java的引用传递问题

      在Java中,基本类型参数的传递是值传递,而对象参数的传递是引用传递,也就是说传递给函数方法的参数是原始对象引用(指针)的副本,因此在函数中如果更改了方法参数引用的内存地址(这种改变一般比较隐蔽)就要特别小心了。例如:

void foo(String text) {
    text = "windows";
}
foo(str); // str 没有被改变
上面的例子中,foo方法中的text参数引用(str对象引用的副本)指向了另外一块内存区域,str对应的内存区域的值并没有被更改。

在我们的项目中有一个类似的例子:

public void A(Map<String, String> map) {

     B(map);
     System.out.println(map.get("key"));  // 打印出null

}

private void B(Map<String, String> map) {

    if(MapUtils.isEmpty(map)) {
        map = new HashMap<>();   // 在此处更改了map引用的内存地址
    }
    
    map.put("key", "value");
}

数据库varchar字段耐操

      在需求还没有完全明确的情况下,一般最好把数据库中的整型字段设置为varchar类型(如果非常确认这个字段一定是整型的话就另当别论)。在我们的需求中有一个拓补树(拓补的数据是从别的系统中同步过来)的展示,数据库中有一个字段topology_id(BIGINT型)表示当前的节点的拓补ID,后来发现源系统中拓补树的有一层是缺失的,我们需要用到字符串拼接来表示这一层节点的拓补ID,这个时候就需要更改字段topology_id的类型


数据库映射不要用枚举

       例如有一个对象User对应于数据库的表user

public class User {

     private SexEnum Sex;   //枚举 F 或者 M
    
     // 省略getter setter  

}
这种情况下,往数据库写并没有问题。然而如果利用mybatis等第三方ORM工具从数据库查询的时候,万一出现sex字段为'f'或者'm'的时候,那么查询可能就会报错,因为SexEnum并没有f和m


一个关于foreach健壮性的示例

        考虑下面一段代码:

public void foreachTest(List<Obj> objList) {

     objList.foreach(obj -> {
         // 做一些操作
     }

}
在上面的foreach中,虽然代码中的操作可能并没有抛出受检查异常,但是可能会抛出运行时异常(尤其是有DB交互或者是网络交互),因此最好将foreach中的操作用try catch包装起来,这样的话循环中的某一个obj操作的失败并不会影响其他obj的操作

public void foreachTest(List<Obj> objList) {

     objList.foreach(obj -> {
        try {
                // 做一些操作
        } catch (Exception e) {
        }
     }


批量交互问题

    在系统中经常会遇到查询的需求,那么最好提供批量查询的接口,避免调用方一遍一遍地调用,增加网络交互


不推荐使用原始类,尽量使用包装类

    在代码中使用包装类可以避免一些NPE的异常,例如:

public static void main(String[] args) {

        Map<String, Integer> map = new HashMap<>();
        map.put("key", null);
        print(map.get("key"));   // 报NPE异常
        
    }
    
    private static void print(int number) {
        System.out.println(number);
    }

二方包的问题

    在开发中,经常会有两个系统间的交互,这个时候如果将系统间的相互交互的对象定义在二方包中,然后两个系统通过引入二方包可以给编程带来便利(例如避免重复的代码)。然而,如果二方包使用不当,可能会带来极大的耦合。

       在我们的A系统和B系统中,我们都引入了同一个二方包library,我们将A系统和B系统所有需要交互的对象都放在library中,这就意味着,A业务和B业务通过library耦合在了一起。

       这个时候,我们可以通过分别构建A系统的客户端库(A的二方包)和B系统的客户端(B的二方包)库来进行解耦合。但是这个时候要注意A和B的客户端库中不要有A业务的业务逻辑。


写代码的模式

     在写代码的过程中,最好考虑一下程序的健壮性,不要等程序写完了再来review代码的健壮性,因为在业务快速迭代的过程中,自己很难有时间在写完代码之后在回过头来仔细看自己写过的代码。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值