为什么重复的bean导致StackOverflowError但没有任何合理的错误消息?

时间:2016-06-21 13:46:38

标签: java spring infinite-loop

以下代码导致StackOverflowError错误,没有任何合理的消息:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

public class DuplicateBeans2 {

   public static class MyClass {
   }


   @Configuration
   public static class Config1 {

      @Bean
      MyClass myClass() {
         return myClass();
      }
   }

   @Configuration
   public static class Config2 {

      @Bean
      MyClass myClass() {
         return myClass();
      }
   }

   public static void main(String[] args) {

      new AnnotationConfigApplicationContext(Config1.class, Config2.class);

   }

}

为什么呢?这个不好的设计不是明确地报告这个吗?

更新

对不起的人,这是我的错,我写错了:

      @Bean
      MyClass myClass() {
         return new MyClass();
      }

1 个答案:

答案 0 :(得分:1)

首先,这里的问题与重复的bean无关。真正的问题是myClass()方法无条件地调用自己。你会对这个类产生同样的效果:

   public class Test {
       public static void main(String[] args) {
           main(args);
       }
   } 
  

为什么?

您遇到了问题,因为myClass()无条件地调用了自己......

  

这个不好的设计不是明确地报告这个吗?

我不会这么说。不能指望Java编译器警告程序员可能会犯的所有错误。我认为在这种情况下它“不值得”因为:

  • 错误很不寻常,
  • 错误的结果是一个例外,非新手程序员很容易诊断

然后考虑这个例子:

  public class A {

      public void test() {
          recurse();
      }

      public void recurse() {
          recurse(); 
      }
  }

现在添加:

  public class B extends A {
      @Override
      public void recurse() {
          // do nothing
      }
  }

如果在test实例上调用A,则会出现StackOverflowError。如果你在B实例上调用它,你就不会。如果编译器警告A.recurse()是错误的,那就错了。