这是递归吗?
public class Test {
Test test = new Test();
public static void main(String[] args) {
new Test();
}
}
关于 instance initalizer 的版本呢? ?
public class Test {
{ Test test = new Test(); }
public static void main(String[] args) {
new Test();
}
}
我在问,因为我更新了 my old answer ,它展示了如何在没有递归的情况下生成 StackOverflowError,但现在我不能 100% 确定上面的代码是否是递归的。
最佳答案
我的看法是递归。不过,我无法找到支持或反对它的好消息来源。因此,我尝试将已知递归函数的汇编代码与 OP 中生成的 java 代码的汇编代码进行比较。这两个汇编代码非常相似,在问题中它发生在调用自身的方法(Constructor)上。
我的测试代码:
public class Test3 {
void printMe() {
printMe();
}
public static void main(String[] args) {
Test3 test = new Test3();
test.printMe();
}
}
打印组件:
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -server -cp 。测试3
相关汇编代码序列,显示函数调用自身:
Decoding compiled method 0x00007f2e2910ac90:
Code:
[Entry Point]
[Constants]
# {method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3'
# [sp+0x40] (sp of caller)
0x00007f2e2910ae00: mov 0x8(%rsi),%r10d
0x00007f2e2910ae04: shl $0x3,%r10
0x00007f2e2910ae08: cmp %rax,%r10
0x00007f2e2910ae0b: jne 0x00007f2e29045b60 ; {runtime_call}
0x00007f2e2910ae11: nopw 0x0(%rax,%rax,1)
0x00007f2e2910ae1c: xchg %ax,%ax
[Verified Entry Point]
0x00007f2e2910ae20: mov %eax,-0x14000(%rsp)
0x00007f2e2910ae27: push %rbp
0x00007f2e2910ae28: sub $0x30,%rsp
0x00007f2e2910ae2c: mov $0x7f2e271213f8,%rdi ; {metadata(method data for {method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')}
0x00007f2e2910ae36: mov 0x64(%rdi),%ebx
0x00007f2e2910ae39: add $0x8,%ebx
0x00007f2e2910ae3c: mov %ebx,0x64(%rdi)
0x00007f2e2910ae3f: mov $0x7f2e27121230,%rdi ; {metadata({method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')}
0x00007f2e2910ae49: and $0x1ff8,%ebx
0x00007f2e2910ae4f: cmp $0x0,%ebx
0x00007f2e2910ae52: je 0x00007f2e2910aec0 ;*aload_0
; - com.vs.soutils.Test3::printMe@0 (line 6)
0x00007f2e2910ae58: mov %rsi,%rdi
0x00007f2e2910ae5b: mov $0x7f2e271213f8,%rbx ; {metadata(method data for {method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')}
0x00007f2e2910ae65: addq $0x1,0xa0(%rbx)
0x00007f2e2910ae6d: mov $0x7f2e271213f8,%rdi ; {metadata(method data for {method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')}
0x00007f2e2910ae77: mov 0x64(%rdi),%ebx
0x00007f2e2910ae7a: add $0x8,%ebx
0x00007f2e2910ae7d: mov %ebx,0x64(%rdi)
0x00007f2e2910ae80: mov $0x7f2e27121230,%rdi ; {metadata({method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')}
0x00007f2e2910ae8a: and $0x7ffff8,%ebx
0x00007f2e2910ae90: cmp $0x0,%ebx
0x00007f2e2910ae93: je 0x00007f2e2910aed4
0x00007f2e2910ae99: mov %rsi,%rdi
0x00007f2e2910ae9c: mov $0x7f2e271213f8,%rbx ; {metadata(method data for {method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')}
0x00007f2e2910aea6: addq $0x1,0xa0(%rbx)
0x00007f2e2910aeae: nop
0x00007f2e2910aeaf: callq 0x00007f2e29045d60 ; OopMap{off=180}
;*invokevirtual printMe
; - com.vs.soutils.Test3::printMe@1 (line 6)
; - com.vs.soutils.Test3::printMe@1 (line 6)
; {optimized virtual_call}
0x00007f2e2910aeb4: add $0x30,%rsp
0x00007f2e2910aeb8: pop %rbp
0x00007f2e2910aeb9: test %eax,0x16461241(%rip) # 0x00007f2e3f56c100
; {poll_return}
0x00007f2e2910aebf: retq
0x00007f2e2910aec0: mov %rdi,0x8(%rsp)
0x00007f2e2910aec5: movq $0xffffffffffffffff,(%rsp)
0x00007f2e2910aecd: callq 0x00007f2e290fdde0 ; OopMap{rsi=Oop off=210}
;*synchronization entry
; - com.vs.soutils.Test3::printMe@-1 (line 6)
; {runtime_call}
0x00007f2e2910aed2: jmp 0x00007f2e2910ae58
0x00007f2e2910aed4: mov %rdi,0x8(%rsp)
0x00007f2e2910aed9: movq $0xffffffffffffffff,(%rsp)
0x00007f2e2910aee1: callq 0x00007f2e290fdde0 ; OopMap{rsi=Oop off=230}
;*synchronization entry
; - com.vs.soutils.Test3::printMe@-1 (line 6)
; - com.vs.soutils.Test3::printMe@1 (line 6)
; {runtime_call}
0x00007f2e2910aee6: jmp 0x00007f2e2910ae99
0x00007f2e2910aee8: nop
0x00007f2e2910aee9: nop
0x00007f2e2910aeea: mov 0x288(%r15),%rax
0x00007f2e2910aef1: mov $0x0,%r10
0x00007f2e2910aefb: mov %r10,0x288(%r15)
0x00007f2e2910af02: mov $0x0,%r10
0x00007f2e2910af0c: mov %r10,0x290(%r15)
0x00007f2e2910af13: add $0x30,%rsp
0x00007f2e2910af17: pop %rbp
0x00007f2e2910af18: jmpq 0x00007f2e2906be20 ; {runtime_call}
现在将其与原始代码的汇编代码进行比较:
Decoding compiled method 0x00007fea24ef0dd0:
Code:
[Entry Point]
[Constants]
# {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test'
# [sp+0x80] (sp of caller)
0x00007fea24ef0f60: mov 0x8(%rsi),%r10d
0x00007fea24ef0f64: shl $0x3,%r10
0x00007fea24ef0f68: cmp %rax,%r10
0x00007fea24ef0f6b: jne 0x00007fea24e29b60 ; {runtime_call}
0x00007fea24ef0f71: nopw 0x0(%rax,%rax,1)
0x00007fea24ef0f7c: xchg %ax,%ax
[Verified Entry Point]
0x00007fea24ef0f80: mov %eax,-0x14000(%rsp)
0x00007fea24ef0f87: push %rbp
0x00007fea24ef0f88: sub $0x70,%rsp
0x00007fea24ef0f8c: mov $0x7fea22943350,%rdx ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')}
0x00007fea24ef0f96: mov 0x64(%rdx),%edi
0x00007fea24ef0f99: add $0x8,%edi
0x00007fea24ef0f9c: mov %edi,0x64(%rdx)
0x00007fea24ef0f9f: mov $0x7fea229431b0,%rdx ; {metadata({method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')}
0x00007fea24ef0fa9: and $0x1ff8,%edi
0x00007fea24ef0faf: cmp $0x0,%edi
0x00007fea24ef0fb2: je 0x00007fea24ef1172 ;*aload_0
; - com.vs.soutils.Test::<init>@0 (line 3)
0x00007fea24ef0fb8: mov %rsi,%rdx
0x00007fea24ef0fbb: mov $0x7fea22943350,%rdi ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')}
0x00007fea24ef0fc5: addq $0x1,0x90(%rdi)
0x00007fea24ef0fcd: mov $0x7fea226a1f10,%rdx ; {metadata(method data for {method} {0x00007fea22543488} '<init>' '()V' in 'java/lang/Object')}
0x00007fea24ef0fd7: mov 0x64(%rdx),%edi
0x00007fea24ef0fda: add $0x8,%edi
0x00007fea24ef0fdd: mov %edi,0x64(%rdx)
0x00007fea24ef0fe0: mov $0x7fea22543488,%rdx ; {metadata({method} {0x00007fea22543488} '<init>' '()V' in 'java/lang/Object')}
0x00007fea24ef0fea: and $0x7ffff8,%edi
0x00007fea24ef0ff0: cmp $0x0,%edi
0x00007fea24ef0ff3: je 0x00007fea24ef1189
0x00007fea24ef0ff9: mov $0x7c0060028,%rdx ; {metadata('com/vs/soutils/Test')}
0x00007fea24ef1003: mov %rsi,0x58(%rsp)
0x00007fea24ef1008: mov 0x60(%r15),%rax
0x00007fea24ef100c: lea 0x10(%rax),%rdi
0x00007fea24ef1010: cmp 0x70(%r15),%rdi
0x00007fea24ef1014: ja 0x00007fea24ef11a0
0x00007fea24ef101a: mov %rdi,0x60(%r15)
0x00007fea24ef101e: mov 0xa8(%rdx),%rcx
0x00007fea24ef1025: mov %rcx,(%rax)
0x00007fea24ef1028: mov %rdx,%rcx
0x00007fea24ef102b: shr $0x3,%rcx
0x00007fea24ef102f: mov %ecx,0x8(%rax)
0x00007fea24ef1032: xor %rcx,%rcx
0x00007fea24ef1035: mov %ecx,0xc(%rax)
0x00007fea24ef1038: xor %rcx,%rcx ;*new ; - com.vs.soutils.Test::<init>@5 (line 5)
0x00007fea24ef103b: mov %rax,%rdx
0x00007fea24ef103e: mov $0x7fea22943350,%rsi ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')}
0x00007fea24ef1048: addq $0x1,0xa0(%rsi)
0x00007fea24ef1050: mov $0x7fea22943350,%rdx ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')}
0x00007fea24ef105a: mov 0x64(%rdx),%esi
0x00007fea24ef105d: add $0x8,%esi
0x00007fea24ef1060: mov %esi,0x64(%rdx)
0x00007fea24ef1063: mov $0x7fea229431b0,%rdx ; {metadata({method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')}
0x00007fea24ef106d: and $0x7ffff8,%esi
0x00007fea24ef1073: cmp $0x0,%esi
0x00007fea24ef1076: je 0x00007fea24ef11ad
0x00007fea24ef107c: mov %rax,%rdx
0x00007fea24ef107f: mov $0x7fea22943350,%rsi ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')}
0x00007fea24ef1089: addq $0x1,0x90(%rsi)
0x00007fea24ef1091: mov $0x7fea226a1f10,%rdx ; {metadata(method data for {method} {0x00007fea22543488} '<init>' '()V' in 'java/lang/Object')}
0x00007fea24ef109b: mov 0x64(%rdx),%esi
0x00007fea24ef109e: add $0x8,%esi
0x00007fea24ef10a1: mov %esi,0x64(%rdx)
0x00007fea24ef10a4: mov $0x7fea22543488,%rdx ; {metadata({method} {0x00007fea22543488} '<init>' '()V' in 'java/lang/Object')}
0x00007fea24ef10ae: and $0x7ffff8,%esi
0x00007fea24ef10b4: cmp $0x0,%esi
0x00007fea24ef10b7: je 0x00007fea24ef11c4
0x00007fea24ef10bd: mov $0x7c0060028,%rdx ; {metadata('com/vs/soutils/Test')}
0x00007fea24ef10c7: mov %rax,0x50(%rsp)
0x00007fea24ef10cc: mov 0x60(%r15),%rax
0x00007fea24ef10d0: lea 0x10(%rax),%rdi
0x00007fea24ef10d4: cmp 0x70(%r15),%rdi
0x00007fea24ef10d8: ja 0x00007fea24ef11db
0x00007fea24ef10de: mov %rdi,0x60(%r15)
0x00007fea24ef10e2: mov 0xa8(%rdx),%rcx
0x00007fea24ef10e9: mov %rcx,(%rax)
0x00007fea24ef10ec: mov %rdx,%rcx
0x00007fea24ef10ef: shr $0x3,%rcx
0x00007fea24ef10f3: mov %ecx,0x8(%rax)
0x00007fea24ef10f6: xor %rcx,%rcx
0x00007fea24ef10f9: mov %ecx,0xc(%rax)
0x00007fea24ef10fc: xor %rcx,%rcx ;*new ; - com.vs.soutils.Test::<init>@5 (line 5)
; - com.vs.soutils.Test::<init>@9 (line 5)
0x00007fea24ef10ff: mov %rax,%rsi
0x00007fea24ef1102: mov $0x7fea22943350,%rdi ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')}
0x00007fea24ef110c: addq $0x1,0xa0(%rdi)
0x00007fea24ef1114: mov %rax,%rsi ;*invokespecial <init>
; - com.vs.soutils.Test::<init>@9 (line 5)
; - com.vs.soutils.Test::<init>@9 (line 5)
0x00007fea24ef1117: mov %rax,0x48(%rsp)
0x00007fea24ef111c: nop
0x00007fea24ef111d: nop
0x00007fea24ef111e: nop
0x00007fea24ef111f: callq 0x00007fea24e29d60 ; OopMap{[72]=Oop [80]=Oop [88]=Oop off=452}
;*invokespecial <init>
; - com.vs.soutils.Test::<init>@9 (line 5)
; - com.vs.soutils.Test::<init>@9 (line 5)
; {optimized virtual_call}
0x00007fea24ef1124: mov 0x48(%rsp),%rsi
0x00007fea24ef1129: mov 0x50(%rsp),%rax
0x00007fea24ef112e: mov %rsi,%r10
0x00007fea24ef1131: shr $0x3,%r10
0x00007fea24ef1135: mov %r10d,0xc(%rax)
0x00007fea24ef1139: mov %rax,%rsi
0x00007fea24ef113c: shr $0x9,%rsi
0x00007fea24ef1140: mov $0x7fea20c23000,%rdi
0x00007fea24ef114a: movb $0x0,(%rsi,%rdi,1) ;*putfield test
; - com.vs.soutils.Test::<init>@12 (line 5)
; - com.vs.soutils.Test::<init>@9 (line 5)
0x00007fea24ef114e: mov 0x58(%rsp),%rsi
0x00007fea24ef1153: mov %rax,%r10
0x00007fea24ef1156: shr $0x3,%r10
0x00007fea24ef115a: mov %r10d,0xc(%rsi)
0x00007fea24ef115e: shr $0x9,%rsi
0x00007fea24ef1162: movb $0x0,(%rsi,%rdi,1) ;*putfield test
; - com.vs.soutils.Test::<init>@12 (line 5)
0x00007fea24ef1166: add $0x70,%rsp
0x00007fea24ef116a: pop %rbp
0x00007fea24ef116b: test %eax,0x15e21f8f(%rip) # 0x00007fea3ad13100
; {poll_return}
0x00007fea24ef1171: retq
0x00007fea24ef1172: mov %rdx,0x8(%rsp)
0x00007fea24ef1177: movq $0xffffffffffffffff,(%rsp)
0x00007fea24ef117f: callq 0x00007fea24ee1d20 ; OopMap{rsi=Oop off=548}
;*synchronization entry
; - com.vs.soutils.Test::<init>@-1 (line 3)
; {runtime_call}
0x00007fea24ef1184: jmpq 0x00007fea24ef0fb8
0x00007fea24ef1189: mov %rdx,0x8(%rsp)
0x00007fea24ef118e: movq $0xffffffffffffffff,(%rsp)
0x00007fea24ef1196: callq 0x00007fea24ee1d20 ; OopMap{rsi=Oop off=571}
;*synchronization entry
; - java.lang.Object::<init>@-1 (line 37)
; - com.vs.soutils.Test::<init>@1 (line 3)
; {runtime_call}
0x00007fea24ef119b: jmpq 0x00007fea24ef0ff9
0x00007fea24ef11a0: mov %rdx,%rdx
0x00007fea24ef11a3: callq 0x00007fea24edda60 ; OopMap{[88]=Oop off=584}
;*new ; - com.vs.soutils.Test::<init>@5 (line 5)
; {runtime_call}
0x00007fea24ef11a8: jmpq 0x00007fea24ef103b
0x00007fea24ef11ad: mov %rdx,0x8(%rsp)
0x00007fea24ef11b2: movq $0xffffffffffffffff,(%rsp)
0x00007fea24ef11ba: callq 0x00007fea24ee1d20 ; OopMap{[88]=Oop rax=Oop off=607}
;*synchronization entry
; - com.vs.soutils.Test::<init>@-1 (line 3)
; - com.vs.soutils.Test::<init>@9 (line 5)
; {runtime_call}
0x00007fea24ef11bf: jmpq 0x00007fea24ef107c
0x00007fea24ef11c4: mov %rdx,0x8(%rsp)
0x00007fea24ef11c9: movq $0xffffffffffffffff,(%rsp)
0x00007fea24ef11d1: callq 0x00007fea24ee1d20 ; OopMap{[88]=Oop rax=Oop off=630}
;*synchronization entry
; - java.lang.Object::<init>@-1 (line 37)
; - com.vs.soutils.Test::<init>@1 (line 3)
; - com.vs.soutils.Test::<init>@9 (line 5)
; {runtime_call}
0x00007fea24ef11d6: jmpq 0x00007fea24ef10bd
0x00007fea24ef11db: mov %rdx,%rdx
0x00007fea24ef11de: callq 0x00007fea24edda60 ; OopMap{[88]=Oop [80]=Oop off=643}
;*new ; - com.vs.soutils.Test::<init>@5 (line 5)
; - com.vs.soutils.Test::<init>@9 (line 5)
; {runtime_call}
0x00007fea24ef11e3: jmpq 0x00007fea24ef10ff
0x00007fea24ef11e8: nop
0x00007fea24ef11e9: nop
0x00007fea24ef11ea: mov 0x288(%r15),%rax
0x00007fea24ef11f1: mov $0x0,%r10
0x00007fea24ef11fb: mov %r10,0x288(%r15)
0x00007fea24ef1202: mov $0x0,%r10
0x00007fea24ef120c: mov %r10,0x290(%r15)
0x00007fea24ef1213: add $0x70,%rsp
0x00007fea24ef1217: pop %rbp
0x00007fea24ef1218: jmpq 0x00007fea24edcce0 ; {runtime_call}
0x00007fea24ef121d: hlt
我们看到构造函数被一遍又一遍地调用。这解释了堆栈溢出,并且似乎是递归的。
关于java - 在类 Test 中实例化类 Test 的成员是递归吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27551338/
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案
我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我