- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我试图使用反射打破 BillPaugh Singleton 解决方案,我能够做到,但在访问 BillPaughSingleTon 解决方案时我可以看到两个构造函数。为什么这样 ?同样通过反复试验发现 HelperClass 内部的行导致了这一点。又是为什么?
BillPaugh类
package creational.BillPaugh;
public class SingleTonBillPaugh
{
private SingleTonBillPaugh instance;
public static SingleTonBillPaugh getInstance()
{
return SingleTonHelper.instance;
}
private SingleTonBillPaugh()
{
System.out.println(Thread.currentThread().getName() + " instance is going to be created");
}
static class SingleTonHelper
{
private static final SingleTonBillPaugh instance = new SingleTonBillPaugh(); //if we remove this line, multiple constructor will not be there. But this line is needed for singleton.
}
}
使用反射打破 SingleTon。
package creational.BillPaugh;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class BreakBillPaughUsingReflection
{
public static void main(String[] args)
{
SingleTonBillPaugh singletonInstance1 = SingleTonBillPaugh.getInstance();
System.out.println("singletonInstance1 " + singletonInstance1);
SingleTonBillPaugh singletonInstance2;
Constructor[] constructors = SingleTonBillPaugh.class.getDeclaredConstructors();
for (Constructor construct : constructors)
{
construct.setAccessible(true);
try
{
singletonInstance2 = (SingleTonBillPaugh) construct.newInstance();
System.out.println("singletonInstance2 " + singletonInstance2);
}
catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e)
{
e.printStackTrace();
}
}// end for
Constructor[] constructors2 = NormalClass.class.getDeclaredConstructors();
}
}
两个构造函数的证明。
最佳答案
这是我的看法:
由于源码中的SingleTonBillPaugh
构造函数是private
,SingleTonBillPaugh$SingleTonHelper
无法访问,所以编译器生成了一个合成构造函数SingleTonBillPaugh$SingleTonHelper
可以 访问。这就是合成方法和构造函数的用途:提供一种访问包含类的私有(private)数据的方法。
在我看来更大的问题是为什么合成构造函数接受一个参数,为什么参数的类型是 SingleTonBillPaugh$1
? (你的截图让它看起来像是一个 SingleTonBillPaugh
实例,但在我的测试中它实际上是一个 SingleTonBillPaugh$1
实例——也就是说,除了SingleTonBillPaugh
和 SingleTonBillPaugh$SingleTonHelper
)。
我对那个问题的回答是:因为否则,将有两个构造函数的区别仅在于一个是合成的并且可由 SingleTonBillPaugh$SingleTonHelper
访问,另一个不是。 Java 要求签名比这更加不同,因此它生成一个类的唯一原因是将合成构造函数与非合成构造函数区分开来。
我们可以看到我们确实有一个 SingleTonBillPaugh$1
类,如果我们 javap -p -c SingleTonBillPaugh\$1
它,我们得到:
class SingleTonBillPaugh$1 {
}
没有比这更小的了,这表明它确实纯粹充当合成构造函数的参数类型。通过使用 javap -p -c SingleTonBillPaugh\$SingleTonHelper
查看 SingleTonBillPaugh$SingleTonHelper
的字节码,我们可以进一步确认:
class SingleTonBillPaugh$SingleTonHelper {
private static final SingleTonBillPaugh instance;
SingleTonBillPaugh$SingleTonHelper();
Code:
0: aload_0
1: invokespecial #2 // Method java/lang/Object."<init>":()V
4: return
static SingleTonBillPaugh access$000();
Code:
0: getstatic #1 // Field instance:LSingleTonBillPaugh;
3: areturn
static {};
Code:
0: new #3 // class SingleTonBillPaugh
3: dup
4: aconst_null
5: invokespecial #4 // Method SingleTonBillPaugh."<init>":(LSingleTonBillPaugh$1;)V
8: putstatic #1 // Field instance:LSingleTonBillPaugh;
11: return
}
注意它是如何(就在最后)调用构造函数的单参数版本(传入 null
)。
事实上,它似乎总是这样做——将一个新参数添加到构造函数参数列表的末尾。如果我更改私有(private)构造函数以接受 String
并更新 SingleTonHelper
以将其传递给 ""
,则合成构造函数最终变为 SingleTonBillPaugh (字符串,SingleTonBillPaugh$1)
。
在下面回答你的问题:
I kept one sysout in no argument constructor and when inner class called no argument constructor of outer class (which supposedly be synthetic constructor) the same sysout is printed. Why so? is it because internally synthetic constructor calls my provided pvt constructor?
没错,合成构造函数调用私有(private)构造函数。像这样的时候,很高兴深入了解字节码:
这是我的 SingleTonBillPaugh.java
副本:
public class SingleTonBillPaugh
{
public static SingleTonBillPaugh getInstance()
{
return SingleTonHelper.instance;
}
private SingleTonBillPaugh()
{
System.out.println(Thread.currentThread().getName() + " instance is going to be created");
}
static class SingleTonHelper
{
private static final SingleTonBillPaugh instance = new SingleTonBillPaugh();
}
}
如果我们编译它,然后使用 javap -p -c SingleTonBillPaugh
,我们得到:
public class SingleTonBillPaugh {
public static SingleTonBillPaugh getInstance();
Code:
0: invokestatic #2 // Method SingleTonBillPaugh$SingleTonHelper.access$000:()LSingleTonBillPaugh;
3: areturn
private SingleTonBillPaugh();
Code:
0: aload_0
1: invokespecial #3 // Method java/lang/Object."<init>":()V
4: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
7: new #5 // class java/lang/StringBuilder
10: dup
11: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
14: invokestatic #7 // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
17: invokevirtual #8 // Method java/lang/Thread.getName:()Ljava/lang/String;
20: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: ldc #10 // String instance is going to be created
25: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: invokevirtual #11 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
31: invokevirtual #12 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
34: return
SingleTonBillPaugh(SingleTonBillPaugh$1);
Code:
0: aload_0
1: invokespecial #1 // Method "<init>":()V
4: return
}
正如我们所见,以源代码形式编写的 SingleTonBillPaugh(SingleTonBillPaugh$1)
构造函数基本上是:
SingleTonBillPaugh(SingleTonBillPaugh$1 unused) {
this();
}
关于java - 为什么拥有静态嵌套类会导致在不在源代码中时添加第二个构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27815030/
所以我试图设置“内容”类的高度,但它似乎不起作用。我对嵌套 DIV 非常陌生,我已经尝试了我在谷歌搜索中发现的修复程序,但似乎没有任何效果。帮助?
好的,所以我一直在四处寻找,但找不到这个问题的答案。但是,我需要将一个 View 嵌套在另一个 View 中。 我有一个 $layout 正在使用我拥有的 default.layout Blade 文
好的,所以我一直在四处寻找,但找不到这个问题的答案。但是,我需要将一个 View 嵌套在另一个 View 中。 我有一个 $layout 正在使用我拥有的 default.layout Blade 文
基本上,我的问题很简单,但它需要知道 Struts 1.1 并且还活着的人。 我尝试构建的伪代码看起来像这样: IF element.method1 = true THEN IF element
我正在尝试将 Excel 嵌套 IF 语句转换为代码语言,但我不确定我是否正确执行此操作,希望能得到一些帮助 这是Excel语句: =IF(D3="Feather",IF(OR(I3>1000,R3=
如果我们创建两个或三个评论并对其进行多次回复,则“有用”链接在单击时会导致问题,它会对具有相同编号的索引执行 ng-click 操作,从而显示具有相同索引的所有文本。如何解决此嵌套问题,以便在单击链接
我在项目中使用Scala,想与Stripe集成,但它只提供Java API。例如,要创建 session ,我使用: val params = new util.HashMap[String, Any
以下代码有一个 Div,其中连续包含四个较小的 Div。四个 Div 中的每一个还包含一个较小的 Div,但此 Div 未显示。我尝试了各种显示和位置组合,看看 div 是否会出现。 classGoa
我在这里有一个问题,循环是: for (i=0; i < n; ++i) for (j = 3; j < n; ++j) { ...
我正在尝试编写代码来显示具有奇数宽度的形状。形状完成后,将其放置在外部形状内。用户将能够输入用于形状的字符和行数。我希望生成一个形状,并通过 for 循环生成一个外部形状。 ***** .
$(".globalTabs").each(function(){ var $globalTabs = $(this); var parent = $globalTabs.parent
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
所以我在这个问题上遇到了一些麻烦,因为变量 i。我只是不确定在第二个 while 循环中如何处理它。对于我的外循环,我知道它将运行 log_4(n^2) 次迭代。对于内部 while 循环,我计算的迭
我似乎找不到在枚举上应用多个 if/then 逻辑的工作方式。 anyOf 不应用条件逻辑,而是表示如果其中任何一个匹配则很好。 allOf 再次不应用条件逻辑,而是测试属性/必填字段的超集。 这是一
如何访问 ReaderT 的内部 monad。 在我的例子中,我有类型: newtype VCSSetupAction a = VCSSetupAction (ReaderT (Maybe VCSCo
这个问题在这里已经有了答案: Add leading zeroes/0's to existing Excel values to certain length (7 个回答) 7年前关闭。 我正在寻
我已经绑定(bind)了很多 AND/OR 函数的组合并且没有运气。 这是我需要创建的: 在 B 列中,我有公司 ID,范围从两个数字字符到六个数字字符。 我需要在 B 列中的每个公司 ID 之前的每
我是 VBA 新手,在尝试编写的宏中使用 If 语句时遇到了一些困难。每个月我都会收到一份 Excel 报告,其中列出了我们公司的哪些员工执行了某些任务。我正在编写的宏旨在将每个员工的数据复制并粘贴到
如果在 B 列中找到单元格 A1 中的值,则使用文本 321 填充除非在 C 列中找到单元格 A1 中的值,在这种情况下填充文本 121反而。如果单元格 A1 的内容不在 B 列或 C 列中,则使用
我有几十万个地址。其中一些在整数之后有粒子。如 4356 A Horse Avenue , 其他格式正常4358 Horse Avenue .有些有“A”,有些有“B”。我正在尝试删除整数和粒子之间的
我是一名优秀的程序员,十分优秀!