当我运行以下Java代码时:
ClassLoader c = new ClassLoader() {
@Override
public Class<?> findClass(String name) {
return Object.class;
}
};
Class<?> cc = c.loadClass(Object[][].class.getName());
System.out.println(cc.getName());
Run Code Online (Sandbox Code Playgroud)
我得到java.lang.Object
的显示终端,即使我代替Object[][].class.getName()
通过[[Ljava.lang.Object
在代码中.问题是我期待控制台显示[[Ljava.lang.Object
.
实际上,在JVM规范中,我可以阅读以下内容:
数组类由Java虚拟机(第5.3.3节)直接创建,而不是由类加载器创建.但是,D的定义类加载器用于创建数组类C的过程中.
既然Object[][]
是一个数组类,我假设findClass
不会使用参数调用我[[Ljava.lang.Object
的元素类型java.lang.Object
.
此外,在"创建数组类"一节中,实际描述了递归算法:
如果组件类型是引用类型,则使用类加载器L递归地应用本节的算法(第5.3节)以便加载并由此创建C的组件类型.
所以我的问题是:
是否可以从 中受益dataclasses.field
,特别是对于默认值,但使用自定义构造函数?我知道@dataclass
注释在生成的中设置默认值__init__
,如果我替换它,就不会再这样做了。那么,是否可以替换生成的__init__
,并仍然在内部调用它?
@dataclass
class A:
l: list[int] = field(default_factory=list)
i: int = field(default=0)
def __init__(self, a: Optional[int]): # completely different args than instance attributes
self.call_dataclass_generated_init() # call generated init to set defaults
if a is not None: # custom settings of attributes
i = 2*a
Run Code Online (Sandbox Code Playgroud)
解决方法是定义__new__
而不是覆盖__init__
,但我更愿意避免这种情况。
这个问题非常接近,但答案仅解决作为代码示例给出的特定用例。另外,我不想使用,__post_init__
因为我需要使用__setattr__
这是静态类型检查的问题,并且它无助于调整__init__
无论如何都会采用的参数。
我也不想使用类方法,我真的希望调用者使用自定义构造函数。
这一个也很接近,但它只是解释为什么新的构造函数替换生成的构造函数,而不是关于如何仍然调用后者(还有一个回复建议使用 Pydantic,但我不想子类化BaseModel
,因为这会弄乱我的继承权)。
因此,简而言之,我希望受益于dataclass …
如何打印许多没有换行符的值?
PRINT *, "foo:", foo, ", bar:", bar, ", baz:", baz
Run Code Online (Sandbox Code Playgroud)