本文旨在提供高效、易于维护的解决方案 Java 物体与特定格式字符串之间的双向映射问题。必要时会出现这种情况 Java 对象的配置信息以特定格式(如 a1:0.1|a2:0.5|fl:true手动编写序列化和反序列化逻辑在传输或存储过程中容易出错难以维护。本文将介绍三种不同的方法使用 JSON 库、利用 Properties 类以及借助 Scanner 优雅地实现对象字段与字符串之间的双向映射避免硬编码提高代码的可读性和可维护性。方案一:使用 JSON 库JSON (JavaScript Object Notation) 它是一种轻量级数据交换格式非常适合序列化和反序列化 Java 对象。通过使用图像 Jackson 这样的 JSON 图书馆可以很容易地使用 Java 对象转换为 JSON 字符串反之亦然。示例代码首先需要添加 Jackson 依赖于你的项目。 如果使用 Maven可以在 pom.xml 以下依赖添加到文件中立即学习Java免费学习笔记(深入)dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId version2.13.0/version !-- 请使用最新版本 -- /dependency然后创建包含 JsonProperty 注解的 Config 类import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public class Config { JsonProperty(a1) private float arg1; JsonProperty(a2) private float arg2; JsonProperty(fl) private boolean flag; // Getters and setters (建议添加) public float getArg1() { return arg1; } public void setArg1(float arg1) { this.arg1 arg1; } public float getArg2() { return arg2; } public void setArg2(float arg2) { this.arg2 arg2; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag flag; } public static void main(String... args) throws JsonProcessingException { Config config new Config(); config.setarg1(0.1f); config.setArg2(0.5f); config.setFlag(true); ObjectMapper mapper new ObjectMapper(); String json mapper.writeValueAsString(config); System.out.println(JSON: json); // 输出: {a1:0.1,a2:0.5,fl:true} Config res mapper.readValue(json, Config.class); System.out.println(arg1: res.getArg1(); // 输出: arg1: 0.1 System.out.println(arg2: res.getArg2(); // 输出: arg2: 0.5 System.out.println(flag: res.isFlag()); // 输出: flag: true } }说明JsonProperty(a1) 注释用于指定 JSON 字符串中的字段 a1 对应于 Config 类的 arg1 字段。ObjectMapper 类负责将 Java 对象序列化为 JSON 字符串 (writeValueAsString)以及将 JSON 字符串反序列化为 Java 对象 (readValue)。务必包含 getter 和 setter 方法Jackson 通过这些方法访问和设置字段值。优点简单易用代码量少。可读性强JSON 格式清晰。通用性强JSON 是一种广泛使用的数据交换格式。缺点需要引入额外的 JSON 库依赖。JSON 字符串可能比其他格式更冗长。方案二:使用 Properties 类Java 的 Properties 类提供了一种简单的存储和加载键值对的方法。可以 Java 对象的字段作为键字段值作为值存储到 Properties 然后将其保存到文件或输出流中。示例代码import java.io.*; import java.util.Properties; public class Config { private static final String A1 a1; private static final String A2 a2; private static final String FL fl; private float arg1; private float arg2; private boolean flag; public float getArg1() { return arg1; } public void setArg1(float arg1) { this.arg1 arg1; } public float getArg2() { return arg2; } public void setArg2(float arg2) { this.arg2 arg2; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag flag; } public void store(OutputStream out) throws IOException { Properties properties new Properties(); properties.setProperty(A1, String.valueOf(arg1); properties.setProperty(A2, String.valueOf(arg2); properties.setProperty(FL, String.valueOf(flag)); properties.store(out, Config data); } public static Config load(InputStream in) throws IOException { Properties properties new Properties(); properties.load(in); Config config new Config(); config.setArg1(Float.parseFloat(properties.getProperty(A1, String.valueOf(0.f)))); config.setArg2(Float.parseFloat(properties.getProperty(A2, String.valueOf(0.f)))); config.setFlag(Boolean.parseBoolean(properties.getProperty(FL, String.valueOf(false)))); return config; } public static void main(String... args) throws IOException { Config config new Config(); config.setarg1(0.1f); config.setArg2(0.5f); config.setFlag(true); File file new File(foo.properties); if (file.exists()) { file.delete(); } file.createNewFile(); try (OutputStream out new FileOutputStream(file, false)) { config.store(out); } Config res null; try (InputStream in new FileInputStream(file)) { res Config.load(in); } System.out.println(arg1: res.getArg1(); // 输出: arg1: 0.1 System.out.println(arg2: res.getArg2(); // 输出: arg2: 0.5 System.out.println(flag: res.isFlag()); // 输出: flag: true } }说明store(OutputStream out) 方法将 Config 存储对象的字段 Properties 在对象中然后将 Properties 将对象写入输出流。load(InputStream in) 该方法从输入流中读取 Properties 对象然后将 Properties 设置对象中的值 Config 在对象字段中。使用常量来定义属性名称提高代码的可读性和可维护性。getProperty(key, defaultValue) 该方法在属性不存在时提供默认值以避免空指针异常。优点简单易用不需要引入额外的依赖。可读性好Properties 清晰的文件格式。支持注释可添加描述信息。缺点只支持字符串类型的键和值需要手动转换类型。复杂的数据结构不适合存储。方案三:使用 Scanner 类Scanner 类可用于分析字符串并将其转换为不同的数据类型。可定制序列化和反序列化逻辑使用分隔符 Java 将对象的字段连接成字符串然后使用 Scanner 字符串的类别分析。示例代码import java.io.IOException; import java.util.Locale; import java.util.Scanner; public class Config { private static final String A1 a1; private static final String A2 a2; private static final String FL fl; private static final String DELIMITER :; private float arg1; private float arg2; private boolean flag; public float getArg1() { return arg1; } public void setArg1(float arg1) { this.arg1 arg1; } public float getArg2() { return arg2; } public void setArg2(float arg2) { this.arg2 arg2; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag flag; } public String serialize() throws IOException { StringBuilder buf new StringBuilder(); buf.append(A1).append(DELIMITER).append(arg1).append( ); buf.append(A2).append(DELIMITER).append(arg2).append( ); buf.append(FL).append(DELIMITER).append(flag).append( ); return buf.toString(); } public static Config deserialize(String str) { Scanner scan new Scanner(str); scan.useDelimiter(DELIMITER |\n); scan.useLocale(Locale.ENGLISH); Config config new Config(); while (scan.hasNext()) { switch (scan.next()) { case A1: config.setArg1(scan.nextFloat()); break; case A2: config.setArg2(scan.nextFloat()); break; case FL: config.setFlag(scan.nextBoolean()); break; } } return config; } public static void main(String... args) throws IOException { Config config new Config(); config.setarg1(0.1f); config.setArg2(0.5f); config.setFlag(true); String str config.serialize(); Config res Config.deserialize(str); System.out.println(arg1: res.getArg1(); // 输出: arg1: 0.1 System.out.println(arg2: res.getArg2(); // 输出: arg2: 0.5 System.out.println(flag: res.isFlag()); // 输出: flag: true } }说明serialize() 方法使用 StringBuilder 将字段名和值拼接成字符串使用 DELIMITER 将字段名和值分开用换行符分开不同的字段。deserialize(String str) 方法使用 Scanner 使用类分析字符串 DELIMITER |\n 将字符串分成字段名和值作为分隔符然后将值设置为 Config 在对象字段中。scan.useLocale(Locale.ENGLISH) 确保浮点数分析采用英文格式避免本地化设置造成的分析错误。优点不需要引入额外的依赖。可定制序列化和反序列化逻辑灵活性高。缺点代码量相对较大。分隔符和数据类型转换容易出错需要仔细处理。可读性相对较差。总结本文介绍了三种不同的实现方法 Java 对象与字符串之间的双向映射。具体的应用场景和需求取决于选择哪种方法。如果需要处理复杂的数据结构并且希望代码简单易用建议使用 JSON 库。如果只需要存储简单的键值对不需要引入额外的依赖可以使用 Properties 类。如果需要定制序列化和反序列化逻辑并且对性能有很高的要求可以使用 Scanner 类。无论选择哪种方法都应尽量避免硬编码映射关系提高代码的可读性和可维护性。定义字段名和分隔符可以减少错误的可能性。同时应编写单元测试以验证序列化和反序列化逻辑的正确性。