如果您不知道Project Lombok可以帮助解决Java的一些烦恼,例如生成带注释的getter和setter,甚至像使用@Data生成简单的JavaBean.它可以真正帮助我,特别是在50个不同的事件对象中,你有多达7个不同的字段需要构建和使用getter隐藏.我可以删除近千行代码.
但是,我担心从长远来看,这将是一个令人遗憾的决定.##Java Freenode当我提到它时,Flamewars会在频道中爆发,提供代码片段会让可能的帮助者感到困惑,人们会抱怨缺少JavaDoc,而且未来的委托人可能会将其全部删除.我真的很喜欢积极的,但我担心的是消极的.
那么:在任何项目中使用Lombok都是安全的吗?积极影响是否值得消极?
我有一个类,其中包含一个看起来像这样的人的信息:
public class Contact {
private String name;
private String location;
private String address;
private String email;
private String phone;
private String fax;
public String toString() {
// Something here
}
// Getters and setters.
}
Run Code Online (Sandbox Code Playgroud)
我想toString()返回this.name +" - "+ this.locations + ...所有变量.我试图使用这个问题所示的反射实现它,但我无法设法打印实例变量.
解决这个问题的正确方法是什么?
前几天我通过手动将类的每个元素写成String来为Java中的类编写toString(),并且我发现使用反射可能会创建一个可以工作的通用toString()方法所有课程.IE它将找出字段名称和值并将它们发送到String.
获取字段名称非常简单,这是同事提出的:
public static List initFieldArray(String className) throws ClassNotFoundException {
Class c = Class.forName(className);
Field field[] = c.getFields();
List<String> classFields = new ArrayList(field.length);
for (int i = 0; i < field.length; i++) {
String cf = field[i].toString();
classFields.add(cf.substring(cf.lastIndexOf(".") + 1));
}
return classFields;
}
Run Code Online (Sandbox Code Playgroud)
使用工厂我可以通过存储一次字段来减少性能开销,第一次调用toString().然而,找到这些价值可能要贵得多.
由于反射的性能,这可能是更实际的假设.但我对反思的想法以及如何使用它来改进我的日常编程感兴趣.
我需要能够遍历整个对象图并记录所有成员字段的所有内容.
例如:对象A具有对象B的集合,其具有对象C的集合,并且A,B,C具有其他字段,等等.
Apache Commons ToStringBuilder是不够的,因为它不会遍历对象图或输出集合的内容.
有没有人知道另一个库会做这个或有一个代码片段来做到这一点?
假设我有一个这样的类(并且还假设所有私有变量:
public class Item {
private String _id = null;
private String _name = null;
private String _description = null;
...
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我想构建这个类的toString()表示,我会在Item类中做这样的事情:
@Override
public String toString() {
return (_id + " " + _name + " " + _description);
}
Run Code Online (Sandbox Code Playgroud)
但是如果我在课堂上说15个私有变量呢?我是否必须像这样写出每个变量的名称?
理想情况下,我想通过遍历此类的私有变量列表并构造字符串表示来完成任务:
@Override
public String toString() {
ArrayList<String> members = getClass().getMembers(); //Some method like this
String string = "";
for(...)
string += members[i] + " ";
}
Run Code Online (Sandbox Code Playgroud)
或者也许是一个toJSON方法,我仍然需要访问这些变量的名称.有什么建议?
对象javadocs和Josh Bloch告诉我们如何实现hashCode/equals,好的IDE将正确处理各种类型的字段.所有的,有些讨论是在这里.
这个问题是关于下一步:你如何确保它们保持良好状态?
特别是,我觉得对于大多数类来说,equals/hashCode应该像Bloch建议的那样实现(以及Eclipse和其他IDE的实现),并考虑到该类中所有非派生的业务逻辑字段.在将新字段添加到类中作为继续工作的一部分时,人们常常忘记将它们添加到equals/hashCode实现中.当两个对象看起来相等时,这可能导致难以发现的错误,但实际上不同于最近引入的字段的值.
一个团队(甚至一个团队!)如何帮助确保类的equals/hashCode继续考虑所有相关字段,因为成员字段会发生变化?
我知道Apache的EqualsBuilder和HashCodeBuilder可以使用反射,这显然会考虑正确的字段,但我想避免使用它们的性能成本.是否有其他方法来标记未包含在equals/hashCode中的字段,应该是什么?静态代码分析,IDE功能,单元测试技术?
我有很多数据对象,我希望能够生成一个String代表每个对象的代码,而不需要为每个对象实现一个toString方法.
我正在考虑获取字段及其值的反射.
还有其他想法吗?
谢谢.
我相信我通过识别哪些字段应该是散列/相等测试的一部分来阅读在编译期间(使用APT)生成equals/hashcode/toString方法的人.我在网上找不到那样的东西(我可能梦见过它?)......
这可以这样做:
public class Person {
@Id @GeneratedValue private Integer id;
@Identity private String firstName, lastName;
@Identity private Date dateOfBirth;
//...
}
Run Code Online (Sandbox Code Playgroud)
对于一个实体(所以我们想要排除一些字段,比如id).
或者像scala案例类,即值对象:
@ValueObject
public class Color {
private int red, green, blue;
}
Run Code Online (Sandbox Code Playgroud)
不仅文件变得更易读和更容易编写,而且它还有助于确保所有属性都是equals/hashcode的一部分(如果您稍后添加其他属性,而不相应地更新方法).
我听说APT在IDE中得不到很好的支持,但我不认为这是一个主要问题.毕竟,测试主要由持续集成服务器运行.
有没有想过这是否已经完成,如果不是为什么?谢谢
我想让我的所有类toString()使用Java反射以相同的方式实现.我想出了两种方法.
创建一个基类,如MyObject重写toString(),我的所有类都会扩展它,但我不确定它是否是一个矫枉过正.
使用Eclipse toString()为每个类生成重写.它的缺点是存在大量代码冗余.
哪种方法首选?如果你使用Eclipse模板,有没有办法在你做New> Class时自动生成它,而不是每次都要做Source> Generate toString()?
除了打印控制台的东西之外你还找到了对象的toString()方法的其他用途吗?
java ×10
reflection ×4
tostring ×4
hashcode ×2
annotations ×1
apt ×1
class ×1
equals ×1
lombok ×1
object ×1
performance ×1