枚举中的valueOf()方法在java 7中不起作用

时间:2016-08-22 07:24:13

标签: java

我正在使用java 6,我的应用程序非常庞大,它是在java 6中开发的。 现在我们尝试将java版本升级为7。

但是当我尝试使用java 7时,它会在枚举类中产生编译错误。 在枚举类中,我定义了valueOf()方法,所以在java 7中它给出了编译错误。

代码

Name clash: The method valueOf(Class<TestEnum>, String) of type TestEnum has the 
same erasure as valueOf(Class<T>, String) of type Enum<E> but does not hide it  TestEnum.java

错误

public static TestEnum valueOf(TestEnum enumType, String value){

        if(value.equalsIgnoreCase(TESTONE.toString()))
            return TestEnum.TESTONE;
        else if(value.equalsIgnoreCase(TESTTWO.toString()))
            return TestEnum.TESTTWO;
        else if(value.equalsIgnoreCase(NONE.toString()))
            return TestEnum.NONE;
        else
            return null;
  }

更新(已解决)

我更改了valueOf()方法,我的文件是编译。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {

            http.antMatcher("/api/**")
              .httpBasic().and()
              .authorizeRequests().anyRequest().fullyAuthenticated().and()
              .csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        }

        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().withUser("test").password("pass").roles("USER")
                .and().withUser("test2").password("pass").roles("ADMIN");
        } 
    }


    @Configuration
    @Order(2)
    public static class FormWebSecurityConfig extends WebSecurityConfigurerAdapter{

        @Autowired
        private UserDetailsService userDetailsService;

        @Autowired
        private LoginSuccessHandler loginSuccessHandler;

        @Override
        protected void configure(HttpSecurity http) throws Exception {

            http.csrf().disable();

            //loginSuccessHandler.setDefaultTargetUrl("/landing");
            http.authorizeRequests().anyRequest().fullyAuthenticated()
                    .and()
                 //   .httpBasic().and()
                    .formLogin()
                    .loginPage("/login")
                    .failureUrl("/login?error")
                    .successHandler(loginSuccessHandler)
                    // login success redirect handled by loginSuccessHandler
                    //.defaultSuccessUrl("/landing")
                    .usernameParameter("email")
                    .permitAll()
                    .and()
                    .logout()
                    .logoutUrl("/logout")
                    .deleteCookies("remember-me")
                    .addLogoutHandler(logoutHandler)
                    //.logoutSuccessHandler(logoutSuccessHandler)
                    .logoutSuccessUrl("/login")
                    .permitAll()
                    .and()
                    .rememberMe();


        }

        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService)
                .passwordEncoder(new BCryptPasswordEncoder());
        } 


        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers(
                    "/**/*.css", "/**/*.png", "/**/*.gif", "/**/*.jpg", "/**/*.js","/**/*.map", "/fonts/*");
        }
    }



}

2 个答案:

答案 0 :(得分:6)

我不确定它为什么在Java 6中工作,因为[以前在Java 6中存在该签名的方法](https://docs.oracle.com/javase/6/docs/api/java/lang/Enum.html#valueOf(java.lang.Class,java.lang.String))(并且从Java 5开始)

但是,为了您的开发人员的理智,我强烈建议您重命名该方法:Enum.valueOf做一些众所周知的事情,并且您正在尝试提供一种不同的方法。这将违反最不意外的原则,并可能导致无意的结果。

TestEnum.forName(String)这样的名称是可能的选择。

此外:枚举类型变量枚举中的switch有点代码味道。你可以更好地表达枚举:

enum TestEnum {
  TESTONE("Test one"),TESTTWO("Test two"), NONE("None");

  private String str;

  private TestEnum(String str) {
    this.str = str;
  }

  @Override public String toString() {
    return str;
  }
}

还有一个额外的好处,就是你不能意外地省略你添加的任何其他枚举值的“字符串”形式。

同样,您可以比显式测试字符串值做得更好:

enum TestEnum {
  /* values */;

  private static HashMap<String, TestEnum> forNameMapping;
  {
    forNameMapping = new HashMap<>();
    for (TestEnum t : TestEnum.values()) {
      forNameMapping.put(t.str.toLowerCase(), t);
    }
  }

  public static TestEnum forName(String str) {
    return forNameMapping.get(str.toLowerCase());
  }
}

答案 1 :(得分:1)

每个枚举都是Enum<T>的子类。 Enum<T>已经使用擦除valueOf(Class,String)定义了一个静态方法。由于无法覆盖静态方法,因此无法使用相同的签名定义静态方法。你必须以不同的方式调用你的方法。