无限递归组合class
Infinite recursion composition class
我的程序中有一个无限递归,我在 class 中有一个字段,它的字段中有相同的 class。他们是单身人士,但这并不是他们不建造的原因。顺便说一句,我编写程序实际上无法删除相数组。
abstract class Phase{
protected String phaseName;
protected char[] keys;
protected String[] commands;
protected Phase[] phases;
protected StringBuilder pattern;
}
class RemotePhase extends Phase{
private static RemotePhase remotePhase;
protected RemotePhase(){
phaseName="Remote.";
commands=new String[]{"Lock/unlock windows", "Toggle door", "Select dog menu"};
setPattern();
//Just below here starts an infinite loop
phases=new Phase[]{FixWindows.getFixWindows(), ToggleDoor.getToggleDoor(), SelectDogPhase.getSelectDogPhase()};
}
public static RemotePhase getRemotePhase(){
if(remotePhase==null){
remotePhase=new RemotePhase();
}
return remotePhase;
}
}
final class FixWindows extends Phase{
private static FixWindows windows;
private RemotePhase remotePhase;
private FixWindows(){
//execution keeps coming here as FixWindows object is never constructed
remotePhase=RemotePhase.getRemotePhase();
}
public static FixWindows getFixWindows(){
if(windows==null){
windows=new FixWindows();
}
return windows;
}
}
我已经尝试将 RemotePhase 设置为静态 class 并且 FixWindows 将其用于其成员,但是我 运行 在尝试覆盖抽象 class 的非静态方法时遇到了错误,并尝试在非静态上下文中从 FixWindows 调用它们。不过,我不想让它成为静态的,因为我必须再做一个 class 才能引用 RemotePhase。
尽管有任何方法可以使这项工作正常进行。谢谢
为什么您需要存储对单例的引用,而您始终可以通过静态 getter 访问它?这将允许从 FixWindows
延迟访问 RemotePhase
,并修复您的循环依赖。因此,最干净的修复方法就是不要在 FixWindows
.
的构造函数中调用 getter
final class FixWindows extends Phase{
private static FixWindows windows;
private FixWindows(){
// does nothing but preventing external classes to instantiate it
}
public static synchronized FixWindows getFixWindows(){
if(windows==null){
windows=new FixWindows();
}
return windows;
}
public void methodThatRequiresTheRemotePhase(){
doSomeStuff(RemotePhase.getRemotePhase());
}
}
顺便提一下,我要警告你,你的代码不是线程安全的。您的 getter 应该同步。
这是对如何打破初始化循环的回答。然而, 更好,因为您首先不需要存储对 RemotePhase
的单例引用。
你的问题是单例初始化器是相互依赖的。
打破它的一种方法是在 RemotePhase
之前分配 RemotePhase
的静态单例字段 RemotePhase
初始化完成。这将确保当初始化进行时,FixWindows
单例对象被构造,它可以找到(部分)初始化的 RemotePhase
单例对象。
所以,机会代码是这样的:
private RemotePhase() {
phaseName = "Remote.";
commands = new String[] { "Lock/unlock windows",
"Toggle door",
"Select dog menu" };
setPattern();
}
private void init() {
phases = new Phase[] { FixWindows.getFixWindows(),
ToggleDoor.getToggleDoor(),
SelectDogPhase.getSelectDogPhase() };
}
public static RemotePhase getRemotePhase() {
if (remotePhase == null) {
remotePhase = new RemotePhase(); // assigns partially initialized object
remotePhase.init(); // completes initialization
}
return remotePhase;
}
你应该避免在另一个中调用构造函数。您可以改用设置器。
我为 FixWindows
展示了这个想法,您可以将同样的想法用于其他子类
abstract class Phase{
protected String phaseName;
protected char[] keys;
protected String[] commands;
protected Phase[] phases;
protected StringBuilder pattern;
}
class RemotePhase extends Phase{
private static RemotePhase remotePhase;
protected RemotePhase(){
phaseName="Remote.";
commands=new String[]{"Lock/unlock windows", "Toggle door", "Select dog menu"};
setPattern();
//Just below here starts an infinite loop
phases=new Phase[]{FixWindows.getFixWindows(this), ToggleDoor.getToggleDoor(), SelectDogPhase.getSelectDogPhase()};
}
public static RemotePhase getRemotePhase(){
if(remotePhase==null){
remotePhase=new RemotePhase();
}
return remotePhase;
}
}
final class FixWindows extends Phase{
private static FixWindows windows;
private RemotePhase remotePhase;
private FixWindows(){
//execution keeps coming here as FixWindows object is never constructed
//remotePhase=RemotePhase.getRemotePhase(); //shoud be deleted
}
public static FixWindows getFixWindows(remotePhase){
if(windows==null){
windows=new FixWindows();
windows.setRemotePahse(remotePhase);
}
return windows;
}
}
我的程序中有一个无限递归,我在 class 中有一个字段,它的字段中有相同的 class。他们是单身人士,但这并不是他们不建造的原因。顺便说一句,我编写程序实际上无法删除相数组。
abstract class Phase{
protected String phaseName;
protected char[] keys;
protected String[] commands;
protected Phase[] phases;
protected StringBuilder pattern;
}
class RemotePhase extends Phase{
private static RemotePhase remotePhase;
protected RemotePhase(){
phaseName="Remote.";
commands=new String[]{"Lock/unlock windows", "Toggle door", "Select dog menu"};
setPattern();
//Just below here starts an infinite loop
phases=new Phase[]{FixWindows.getFixWindows(), ToggleDoor.getToggleDoor(), SelectDogPhase.getSelectDogPhase()};
}
public static RemotePhase getRemotePhase(){
if(remotePhase==null){
remotePhase=new RemotePhase();
}
return remotePhase;
}
}
final class FixWindows extends Phase{
private static FixWindows windows;
private RemotePhase remotePhase;
private FixWindows(){
//execution keeps coming here as FixWindows object is never constructed
remotePhase=RemotePhase.getRemotePhase();
}
public static FixWindows getFixWindows(){
if(windows==null){
windows=new FixWindows();
}
return windows;
}
}
我已经尝试将 RemotePhase 设置为静态 class 并且 FixWindows 将其用于其成员,但是我 运行 在尝试覆盖抽象 class 的非静态方法时遇到了错误,并尝试在非静态上下文中从 FixWindows 调用它们。不过,我不想让它成为静态的,因为我必须再做一个 class 才能引用 RemotePhase。
尽管有任何方法可以使这项工作正常进行。谢谢
为什么您需要存储对单例的引用,而您始终可以通过静态 getter 访问它?这将允许从 FixWindows
延迟访问 RemotePhase
,并修复您的循环依赖。因此,最干净的修复方法就是不要在 FixWindows
.
final class FixWindows extends Phase{
private static FixWindows windows;
private FixWindows(){
// does nothing but preventing external classes to instantiate it
}
public static synchronized FixWindows getFixWindows(){
if(windows==null){
windows=new FixWindows();
}
return windows;
}
public void methodThatRequiresTheRemotePhase(){
doSomeStuff(RemotePhase.getRemotePhase());
}
}
顺便提一下,我要警告你,你的代码不是线程安全的。您的 getter 应该同步。
这是对如何打破初始化循环的回答。然而,RemotePhase
的单例引用。
你的问题是单例初始化器是相互依赖的。
打破它的一种方法是在 RemotePhase
之前分配 RemotePhase
的静态单例字段 RemotePhase
初始化完成。这将确保当初始化进行时,FixWindows
单例对象被构造,它可以找到(部分)初始化的 RemotePhase
单例对象。
所以,机会代码是这样的:
private RemotePhase() {
phaseName = "Remote.";
commands = new String[] { "Lock/unlock windows",
"Toggle door",
"Select dog menu" };
setPattern();
}
private void init() {
phases = new Phase[] { FixWindows.getFixWindows(),
ToggleDoor.getToggleDoor(),
SelectDogPhase.getSelectDogPhase() };
}
public static RemotePhase getRemotePhase() {
if (remotePhase == null) {
remotePhase = new RemotePhase(); // assigns partially initialized object
remotePhase.init(); // completes initialization
}
return remotePhase;
}
你应该避免在另一个中调用构造函数。您可以改用设置器。
我为 FixWindows
展示了这个想法,您可以将同样的想法用于其他子类
abstract class Phase{
protected String phaseName;
protected char[] keys;
protected String[] commands;
protected Phase[] phases;
protected StringBuilder pattern;
}
class RemotePhase extends Phase{
private static RemotePhase remotePhase;
protected RemotePhase(){
phaseName="Remote.";
commands=new String[]{"Lock/unlock windows", "Toggle door", "Select dog menu"};
setPattern();
//Just below here starts an infinite loop
phases=new Phase[]{FixWindows.getFixWindows(this), ToggleDoor.getToggleDoor(), SelectDogPhase.getSelectDogPhase()};
}
public static RemotePhase getRemotePhase(){
if(remotePhase==null){
remotePhase=new RemotePhase();
}
return remotePhase;
}
}
final class FixWindows extends Phase{
private static FixWindows windows;
private RemotePhase remotePhase;
private FixWindows(){
//execution keeps coming here as FixWindows object is never constructed
//remotePhase=RemotePhase.getRemotePhase(); //shoud be deleted
}
public static FixWindows getFixWindows(remotePhase){
if(windows==null){
windows=new FixWindows();
windows.setRemotePahse(remotePhase);
}
return windows;
}
}