- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我再次使用java,在这样做时,我遇到了一个有趣的问题。
我正在尝试为自己编写一个小注册服务。如果某个类型的对象通过其构造函数实例化,它将从我的注册服务中检索一个 ID,并将其添加到对象的服务列表中。
这是一个示例对象
public class Test {
private final Long id;
public Test() {
this.id = TestRegistration.register(this);
throw new IllegalAccessError();
}
public Long getId() {
return this.id;
}
}
这是一个示例服务
public class TestRegistration {
private final static Map<Long, Test> registration = new HashMap<>();
protected final static long register(final Test pTest) {
if (pTest.getId() != null) {
throw new IllegalStateException();
}
long freeId = 0;
while (registration.containsKey(freeId)) {
freeId = freeId + 1;
}
registration.put(freeId, pTest);
return freeId;
}
protected final static Test get(final long pId) {
return registration.get(pId);
}
}
现在如您所见,我的类 Test
的构造函数根本无法成功执行,因为它总是抛出 IllegalAccessError
。但是在引发此错误之前,我的 TestRegistration
类的方法 register(...)
在构造函数中被调用。在此方法中,它被添加到注册Map
中。例如,如果我运行这段代码
public static void main(final String[] args) {
try {
final Test t = new Test();
} catch (final IllegalAccessError e) {
}
final Test t2 = TestRegistration.get(0);
System.out.println(t2);
}
我的TestRegistration
实际上包含调用我的Test
类的构造函数时创建的对象,我可以(这里使用变量t2
)访问它,即使它最初没有成功创建。
我的问题是,我能否以某种方式从 TestRegistration 类中检测 Test 的构造函数是否成功执行,没有任何异常或其他中断?
在你问我为什么首先抛出这个异常之前,这是我的答案。测试可能有我还不知道的潜在子类,但仍将在我的 TestRegistration 类中注册。但由于我对这些子类的结构没有影响,我无法判断它们的构造函数是否会抛出异常。
最佳答案
这似乎不可能。
我已经从下面的 JLS 中收集到了最好的信息。
从中可以看出,构造函数体的执行是对象创建的最后一步。
因此,我没有看到任何证据表明引发异常会导致任何不会发生的事情,您可以检查执行是否成功(除了其余的部分)显然是构造函数的主体)。
这可能看起来不是特别令人信服,尽管我不相信您会找到比这更具体的东西(毕竟,证明某些东西不存在是出了名的困难)。
<小时/>我建议将修改外部数据的逻辑放在其他地方。
要求在构造对象后显式调用 register
方法(在 TestRegistration 类中或在对象本身中)并非完全不合理。
它也可以工作,而不是直接调用构造函数,有一个包含返回对象的方法的类(这听起来很像工厂设计模式),然后你可以在其中放置这个外部修改逻辑。
<小时/>来自 JLS:
<小时/>15.9.4. Run-Time Evaluation of Class Instance Creation Expressions
At run time, evaluation of a class instance creation expression is as follows.
First, if the class instance creation expression is a qualified class instance creation expression, the qualifying primary expression is evaluated. If the qualifying expression evaluates to null, a NullPointerException is raised, and the class instance creation expression completes abruptly. If the qualifying expression completes abruptly, the class instance creation expression completes abruptly for the same reason.
Next, space is allocated for the new class instance. If there is insufficient space to allocate the object, evaluation of the class instance creation expression completes abruptly by throwing an OutOfMemoryError.
The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.12.5).
Next, the actual arguments to the constructor are evaluated, left-to-right. If any of the argument evaluations completes abruptly, any argument expressions to its right are not evaluated, and the class instance creation expression completes abruptly for the same reason.
Next, the selected constructor of the specified class type is invoked. This results in invoking at least one constructor for each superclass of the class type. This process can be directed by explicit constructor invocation statements (§8.8) and is specified in detail in §12.5.
The value of a class instance creation expression is a reference to the newly created object of the specified class. Every time the expression is evaluated, a fresh object is created.
12.5. Creation of New Class Instances
...
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
If this constructor begins with an explicit constructor invocation (§8.8.7.1) of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.
This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5.
Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.
关于java - 查看构造函数是否执行成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49350193/
我正在使用 jQuery 的 $.ajax 函数来提交表单,它可以工作,但成功正是我遇到问题的地方。这是我的代码: $("#form").submit(function () { $.
我正在使用动态分页。 我需要在开始另一个事件之前取消 jQuery ajax 中的 success 事件。 我已经设置了一个等于$.ajax()的变量,在这样做之前,无论如何我都会调用abort。 问
如果我错了,请纠正我,但我对 $.post 成功/失败的理解是,如果 url 有效,这将返回成功。唯一会返回失败的情况是 url 无效。 如果这是真的,我如何验证成功函数?我问的原因是无论发生什么,即
HANDLE hFile = CreateFile(LPCTSTR("filename"), // name of the write
我正在使用以下代码发送短信。但这似乎不会在未发送短信时产生异常。例如,当没有足够的钱发送时,我仍然会去 smsSucces();有没有人知道解决此问题的方法以确保它已发送? private b
我正在尝试将字符串转换为 DateTime,在一台计算机上,它工作正常,但在另一台计算机上,它却不行!它运行的计算机运行的是 32 位 Windows 7,它不运行的计算机运行的是 64 位 Wind
我在页面上使用表单让用户输入将用于各种目的的图像的 url。我正在编写一个 ajax 方法来确定他们提供的 url 是否实际上是图像。到目前为止,我已经这样做了: $(document).on('re
我在 jquery 中对 php 脚本进行 ajax 调用。但是 php 脚本需要返回什么才能触发 ajax 中的成功/错误处理程序。所以这是 ajax: $.ajax({ data:
几个简单的问题: 对于 native 和 Flash/Silverlight 垫片来说,成功事件是“规范化”事件吗?记录的示例表明它仅适用于 Flash/Silverlight 对象准备就绪的情况。
这个问题不太可能对任何 future 的访客有帮助;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,通常不适用于互联网的全局受众。如需帮助使这个问题更广泛适用,visit the h
我尝试使用新的 Groovy Grape Groovy 1.6-beta-2 中的功能,但我收到一条错误消息; unable to resolve class com.jidesoft.swing.J
我正在使用 sequelize/nodejs/express/react 将实体持久化到 postgres 数据库 我有两个主要模型,国家和事件,我正在使用该应用程序,并且有一个名为“保存到数据库”的
我有以下代码,其中有 2 个电子邮件输入字段,我需要验证它们是否相同,并且使用 jQuery validate equalTo 成功运行。 Email Address
我正在尝试找出解决此问题的正确方法。 假设我们有一家元素商店。这些项目可以编辑、删除和创建。编辑或添加项目时,路线更改为/item/add 或/item/edit/{id}。 在 saga 成功添加或
这个问题已经有答案了: How do I return the response from an asynchronous call? (42 个回答) 已关闭 8 年前。 我有这段代码,警报工作正常
Closed. This question needs to be more focused。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅关注editing this post的一个问题。
我想在单击超链接 (.remove_resort) 时(成功的 ajax 调用后)删除超链接的(父)跨度。 虽然ajax调用成功,但是最后span并没有被移除。这里出了什么问题? 请记住:有几个类
我正在编写一个非常简单的程序来将鼠标剪辑到指定的窗口。它从系统托盘运行,没有可见窗口。由于同一窗口会有多个实例,因此它使用 EnumWindows() 迭代每个顶级窗口,并将它们的 hwnd 与 Ge
我正在尝试找出如何执行 if 语句,以便如果玩家的击球率超过 0.250,则会为成功的 tr 添加一个类别。 我发现了以下堆栈问题,但我不确定可以使用或应该使用哪种方式以及如何使用这些堆栈问题。 ht
我是 Prolog 的新手,我正在尝试解决这个练习: Define a predicate greater_than/2 that takes two numerals in the notation
我是一名优秀的程序员,十分优秀!