将枚举转换为字符串时的奇怪行为

Posted

技术标签:

【中文标题】将枚举转换为字符串时的奇怪行为【英文标题】:Strange behavior when converting enum to string 【发布时间】:2021-12-24 19:19:10 【问题描述】:

我有一个枚举类 SearchableFieldname, version 和查询类

private Map<SearchableField,Object> query;
private Map<SearchableField, Long> field;
private Map<SearchableField,Long> sort;

我想强制 API 主体仅对字段(名称、版本)进行搜索。我发现的问题,有时它工作正常,我得到了我想要的结果,有时没有通过仅重新启动应用程序对我的代码进行任何更改,它突然不再工作,我得到了这个错误。重新启动应用程序后,对我的代码和正文 JSON 都没有进行任何更改,它运行良好而不会出现错误。

我试图将地图 转换为 map 但我得到了相同的行为

        Map<String,Object> query = doc.getQuery().entrySet().stream()
                .collect(Collectors.toMap(e -> e.getKey().name(), Map.Entry::getValue));

请问我该如何避免这个问题呢?


    "stack": "java.lang.ClassCastException: class java.lang.String cannot be cast to class com.example.SearchableField 
    (java.lang.String is in module java.base of loader 'bootstrap'; com.example.SearchableField is in unnamed module of loader 
    io.quarkus.bootstrap.classloading.QuarkusClassLoader @38a1c423)\r\n\tat com.example.model.Service.lambda$streamAllServices$0(Service.java:32)
    \r\n\tat java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:177)
    \r\n\tat java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
    \r\n\tat java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1746)
    \r\n\tat java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    \r\n\tat java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    \r\n\tat java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
    \r\n\tat java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    \r\n\tat java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
    \r\n\tat com.example.model.Service.streamAllServices(Service.java:32)
    \r\n\tat com.example.rest.ServiceQueryCommand.getAllServices(ServiceQueryCommand.java:33)
    \r\n\tat com.example.rest.ServiceQueryCommand_Subclass.getAllServices$$superforward1(ServiceQueryCommand_Subclass.zig:126)
    \r\n\tat com.example.rest.ServiceQueryCommand_Subclass$$function$$1.apply(ServiceQueryCommand_Subclass$$function$$1.zig:33)
    \r\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
    \r\n\tat io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
    \r\n\tat io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:49)
    \r\n\tat io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:516)
    \r\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
    \r\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
    \r\n\tat io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
    \r\n\tat com.example.rest.ServiceQueryCommand_Subclass.getAllServices(ServiceQueryCommand_Subclass.zig:207)
    \r\n\tat com.example.rest.ServiceQueryCommand$quarkusrestinvoker$getAllServices_1c4b93897207492bfe00d441fe9872b666e1a566.invoke
    (ServiceQueryCommand$quarkusrestinvoker$getAllServices_1c4b93897207492bfe00d441fe9872b666e1a566.zig:39)
    \r\n\tat org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
    \r\n\tat org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:7)
    \r\n\tat org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:141)
    \r\n\tat org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext$1$1.handle(VertxResteasyReactiveRequestContext.java:72)
    \r\n\tat org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext$1$1.handle(VertxResteasyReactiveRequestContext.java:69)
    \r\n\tat io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)
    \r\n\tat io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:63)
    \r\n\tat io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:38)
    \r\n\tat io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
    \r\n\tat io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
    \r\n\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
    \r\n\tat io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
    \r\n\tat io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    \r\n\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    \r\n\tat java.base/java.lang.Thread.run(Thread.java:829)"

【问题讨论】:

【参考方案1】:

虽然没有提供查询类的结构/数据,但我建议修改枚举以具有字符串版本/字段。类似的东西

enum SearchableField
  name("NAME"), version("VERSION");

  private final String fieldName ; 
  
  SearchableField(final String fieldName)
    this.fieldName = fieldName;
  
  
  public String getFieldName()
    return this.fieldName;
  

这样,您将获得所需的枚举值的可良好预测的字符串版本。名称可以通过 getFieldName() 方法获取。

【讨论】:

感谢您的回答,我已经进行过这样的测试,但我的行为总是相同 可以添加Query的内容吗?或者 doc.getQuery() 返回什么? 文档是这样的 "query": "version": "$gte" : 0, "$lte" : 2 , "field": "key" : 1, "version":1 , "sort": "version":1 , "offset":0, "limit":2, "lang" : "fr"

以上是关于将枚举转换为字符串时的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

使用 C 的 getline() 时的奇怪行为

使用单词边界 [[:<:]] 和 [[:>]] 时的奇怪行为

sizeWithFont - 包含 & 字符时的奇怪行为

Double.ToString() 的奇怪行为

将 UIButton 添加到 UICollectionViewCell 时的奇怪行为

分配给整数时的字符串数组会产生一个奇怪的值[重复]