gpt4 book ai didi

Java创建具有深度空对象的实例

转载 作者:行者123 更新时间:2023-11-30 03:55:17 26 4
gpt4 key购买 nike

我有一个嵌套了自定义对象类型的类。当我创建实例时,我希望使用默认值以及嵌套对象创建实例。我正在检查 Apache Bean Utils 中是否有可用的实用程序类,但还没有运气。有什么简单的方法可以做到这一点吗?如果没有,我必须编写一个递归函数来做到这一点。例如

A{
int x;
B b;
C c;
}

B{
boolean y;
D d;
}

D{
String z;
}

Object a = A.class.newInstance();

上面应该给我一个如下所示的对象,其中 a、b、c、d 填充有默认值(仅适用于基元)

 a 
|--> x (=0)
|
|--> b
|
|--> c
|--> y (=false)
|
|--> d
|--> x (=null)

在不更改实际类的结构的情况下,我想创建一个深度创建空对象的实例。任何想法都高度赞赏!

最佳答案

这将实现您想要的功能,但有一些警告:

  • 它假设有一个默认构造函数。
  • 它会跳过基元。
  • 它会跳过已经初始化的对象。
  • 它只会初始化指定的包(startsWith match),以避免初始化其他变得非常困惑的东西,例如 HashMap 等。
  • 仅使用简单对象进行了测试。
  • 如果您设置了安全管理器策略,您可能无法访问这些字段。
  • 如果存在任何类型的递归循环,例如 obj_A 有一个 obj_B 有一个 obj_A,那么它将因堆栈溢出而失败。
  • 它不会访问和设置父类(super class)的值(但可以这样做)。

我会问这是否是最好的解决方案,因为如果对象深处的情况与预期不一样,它很容易失败。

初始化器.java

import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;

import org.example.something.A;

public class Initilizer {

public static void initialize(Object object, Set<String> packages)
throws IllegalArgumentException,
IllegalAccessException {
Field[] fields = object.getClass().getDeclaredFields();

for (Field field : fields) {
String fieldName = field.getName();
Class<?> fieldClass = field.getType();

// skip primitives
if (fieldClass.isPrimitive()) {
System.out.println("Skipping primitive: " + fieldName);
continue;
}

// skip if not in packages
boolean inPackage = false;
for (String pack : packages) {
if (fieldClass.getPackage().getName().startsWith(pack)) {
inPackage = true;
}
}
if (!inPackage) {
System.out.println("Skipping package: "
+ fieldClass.getPackage().getName());
continue;
}

// allow access to private fields
boolean isAccessible = field.isAccessible();
field.setAccessible(true);

Object fieldValue = field.get(object);
if (fieldValue == null) {
System.out.println("Initializing: " + fieldName);
try {
field.set(object, fieldClass.newInstance());
} catch (IllegalArgumentException | IllegalAccessException
| InstantiationException e) {
System.err.println("Could not initialize "
+ fieldClass.getSimpleName());
}
} else {
System.out
.println("Field is already initialized: " + fieldName);
}

fieldValue = field.get(object);

// reset accessible
field.setAccessible(isAccessible);

// recursive call for sub-objects
initialize(fieldValue, packages);
}

}

public static void main(String[] args) throws Exception {

A a = new A();

// Packages to initialize
Set<String> packages = new HashSet<>();
packages.add("com.example");
packages.add("org.example");

initialize(a, packages);
}
}

A.java

package org.example.something;

import com.example.other.B;

public class A {

private int x;

private B b;

private B be = new B();

private C c;

}

B.java

package com.example.other;

public class B {

private boolean y;

private D d;

}

C.java

package org.example.something;
import java.util.HashMap;

public class C {

private HashMap doNotInit;

}

D.java

package com.example.other;

public class D {

private String s;

}

输出

Skipping primitive: x
Initializing: b
Skipping primitive: y
Initializing: d
Skipping package: java.lang
Field is already initialized: be
Skipping primitive: y
Initializing: d
Skipping package: java.lang
Initializing: c
Skipping package: java.util

关于Java创建具有深度空对象的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23373421/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com