You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 22:57:02