Java对象赋值时能否仅保留已赋值属性,过滤无值的多余属性?
结论
你当前的写法无法实现需求,且Java本身无法让ClassA实例彻底去掉已定义的b、c属性,你要的效果可以通过属性拷贝+自定义toString实现,具体逻辑如下:
原因说明
你代码中的ca2 = ca1是Java的引用赋值,执行后ca2和ca1会指向堆内存中的同一个ClassA对象,两者属性完全一致,不存在“仅包含部分属性”的可能。
另外Java是静态强类型语言,类结构编译后就固定了,只要ClassA的定义里声明了b、c属性,所有实例都会携带这两个属性,哪怕值为null,无法在运行时删除属性。你要求的“不包含未赋值的b和c”本质是打印时不展示null属性,配合仅拷贝非null属性的逻辑即可实现。
实现方案
1. 替换引用赋值为非null属性拷贝
不要直接赋值引用,单独写非null属性拷贝逻辑,将ca1的非null属性拷贝到新的ClassA实例中:
// 可以写在ClassA类里作为工具方法,也可以放在业务工具类中 public static ClassA copyNonNullFrom(ClassA source) { ClassA target = new ClassA(); if (source.getA() != null) { target.setA(source.getA()); } if (source.getB() != null) { target.setB(source.getB()); } if (source.getC() != null) { target.setC(source.getC()); } return target; }
修改Test类的赋值逻辑:
public class Test { public static void main(String[] args) { ClassA ca1 = new ClassA(); ca1.setA("One"); // 替换原来的ca2 = ca1 ClassA ca2 = ClassA.copyNonNullFrom(ca1); System.out.println(ca2); } }
2. 自定义toString方法过滤null属性
在ClassA中重写toString方法,仅输出值不为null的属性:
@Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(getClass().getSimpleName()) .append("@") .append(Integer.toHexString(hashCode())) .append("["); // 拼接非null属性 List<String> nonNullAttrs = new ArrayList<>(); if (a != null) { nonNullAttrs.add("a=" + a); } if (b != null) { nonNullAttrs.add("b=" + b); } if (c != null) { nonNullAttrs.add("c=" + c); } sb.append(String.join(",", nonNullAttrs)); sb.append("]"); return sb.toString(); }
修改后程序输出结果为:ClassA@xxxx[a=One],符合你的预期。
内容的提问来源于stack exchange,提问作者KayWe
相关产品推荐
相关产品推荐

