高唐做网站建设的公司,求个网站谢谢啦,seo技术教程网,苏州最新情况最新消息今天Java中NULL用法的简单示例#xff1a; public Employee getByName(String name) {int id database.find(name);if (id 0) {return null;}return new Employee(id);
}这种方法有什么问题#xff1f; 它可能返回NULL而不是对象-这是错误的。 在面向对象的范例中#xff0c… Java中NULL用法的简单示例 public Employee getByName(String name) {int id database.find(name);if (id 0) {return null;}return new Employee(id);
} 这种方法有什么问题 它可能返回NULL而不是对象-这是错误的。 在面向对象的范例中 NULL是一种可怕的做法应不惜一切代价避免使用NULL 。 关于此出版物已经有很多意见包括“ 空引用” Tony Hoare撰写的《十亿美元的错误》演讲和David West撰写的整本《 Object Thinking 》。 在这里我将尝试总结所有参数并举例说明如何避免使用NULL并使用适当的面向对象的结构代替它们。 基本上可以使用NULL两种替代方法。 第一个是Null Object设计模式最好的方法是使其成为常数 public Employee getByName(String name) {int id database.find(name);if (id 0) {return Employee.NOBODY;}return Employee(id);
} 第二种可能的替代方法是在无法返回对象时抛出异常 从而快速失败 public Employee getByName(String name) {int id database.find(name);if (id 0) {throw new EmployeeNotFoundException(name);}return Employee(id);
} 现在让我们看看反对NULL的参数。 除了上面提到的Tony Hoare的演示文稿和David West的书以外我在写这篇文章之前还阅读了这些出版物Robert Martin的Clean Code Steve McConnell的Code Complete John Sonmez的“ No”到“ Null” 是否返回无效的不良设计 StackOverflow上的讨论。 临时错误处理 每次获取对象作为输入时都必须检查它是否为NULL或有效的对象引用。 如果忘记检查则NullPointerException NPE可能会在运行时中断执行。 因此您的逻辑将受到多次检查以及if / then / else分支的污染 // this is a terrible design, dont reuse
Employee employee dept.getByName(Jeffrey);
if (employee null) {System.out.println(cant find an employee);System.exit(-1);
} else {employee.transferTo(dept2);
} 这就是应该用C和其他命令式程序语言处理异常情况的方式。 OOP引入了异常处理主要是为了摆脱这些临时的错误处理块。 在OOP中我们让异常冒泡直到它们到达应用程序范围的错误处理程序并且我们的代码变得更加简洁明了 dept.getByName(Jeffrey).transferTo(dept2); 考虑NULL引用是过程编程的继承请改用1Null对象或2异常。 模棱两可的语义 为了明确传达其含义必须将函数getByName()命名为getByNameOrNullIfNotFound() 。 每个返回对象或NULL函数都应该发生同样的情况。 否则对于代码阅读器来说模棱两可是不可避免的。 因此为了保持语义的明确性应为函数指定更长的名称。 要摆脱这种歧义请始终返回真实对象空对象或引发异常。 有人可能会争辩说为了性能起见我们有时必须返回NULL 。 例如当地图中没有这样的项目时Java中接口Map get()方法将返回NULL Employee employee employees.get(Jeffrey);
if (employee null) {throw new EmployeeNotFoundException();
}
return employee; 由于Map使用NULL 因此此代码仅搜索一次Map 。 如果我们将Map重构以便其方法get()在未找到任何内容的情况下将引发异常则我们的代码将如下所示 if (!employees.containsKey(Jeffrey)) { // first searchthrow new EmployeeNotFoundException();
}
return employees.get(Jeffrey); // second search 显然此方法的速度是第一个方法的两倍。 该怎么办 Map界面对其作者没有冒犯具有设计缺陷。 它的方法get()应该一直返回一个Iterator以便我们的代码如下所示 Iterator found Map.search(Jeffrey);
if (!found.hasNext()) {throw new EmployeeNotFoundException();
}
return found.next(); 顺便说一句这正是C STL map :: find方法的设计方式。 计算机思维与对象思维 有人知道Java中的对象是指向数据结构的指针而NULL是指向0x00000000的指针在Intel x86处理器中为0x00000000 if (employee null)可以理解if (employee null)语句。 但是如果您开始以对象为对象进行思考那么这种说法就没有意义了。 这是从对象角度看我们的代码的样子 - Hello, is it a software department?
- Yes.
- Let me talk to your employee Jeffrey please.
- Hold the line please...
- Hello.
- Are you NULL? 对话中的最后一个问题听起来很奇怪不是吗 相反如果他们在我们请求与Jeffrey通话后挂断电话这会给我们造成麻烦异常。 此时我们尝试再次致电或通知主管我们无法联系Jeffrey并完成更大的交易。 或者他们可以让我们与不是Jeffrey的其他人交谈但是可以帮助我们解决大多数问题或者在我们需要“特定于Jeffrey”的东西时拒绝帮助空对象。 缓慢失败 上面的代码没有快速失败 而是尝试缓慢消失从而杀死了其他人。 它没有让所有人都知道出了什么问题并且应该立即开始异常处理而是向客户端隐藏了此故障。 该参数与上面讨论的“临时错误处理”非常接近。 最好使代码尽可能脆弱并在必要时让代码中断。 使您的方法对它们操作的数据极为苛刻。 如果提供的数据不足或根本不适合该方法的主要使用场景请让他们通过引发异常来进行抱怨。 否则返回一个Null对象该对象暴露一些常见行为并在所有其他调用上引发异常 public Employee getByName(String name) {int id database.find(name);Employee employee;if (id 0) {employee new Employee() {Overridepublic String name() {return anonymous;}Overridepublic void transferTo(Department dept) {throw new AnonymousEmployeeException(I cant be transferred, Im anonymous);}};} else {employee Employee(id);}return employee;
}可变和不完整的对象 通常 强烈建议设计时牢记不变性的对象。 这意味着对象在实例化过程中会获得所有必需的知识并且在整个生命周期中都不会改变其状态。 通常在延迟加载中使用NULL值以使对象不完整且可变。 例如 public class Department {private Employee found null;public synchronized Employee manager() {if (this.found null) {this.found new Employee(Jeffrey);}return this.found;}
} 该技术尽管被广泛使用但却是OOP中的反模式。 主要是因为它使对象负责计算平台的性能问题而这是Employee对象不应该意识到的。 对象不必管理状态并公开其与业务相关的行为而必须处理其自身结果的缓存-这就是延迟加载的意义所在。 缓存不是员工在办公室里做的事情对吗 解决方案 请勿以上述原始方式使用延迟加载。 相反请将此缓存问题移至应用程序的另一层。 例如在Java中您可以使用面向方面的编程方面。 例如 jcabi-aspects具有Cacheable批注用于缓存方法返回的值 import com.jcabi.aspects.Cacheable;
public class Department {Cacheable(forever true)public Employee manager() {return new Employee(Jacky Brown);}
} 我希望这种分析令人信服您将停止NULL您的代码 相关文章 您可能还会发现以下有趣的帖子 Java代码中的典型错误 实用程序类的OOP替代 避免字符串串联 对象应该是不可变的 翻译自: https://www.javacodegeeks.com/2014/09/why-null-is-bad.html