【问题标题】:Java generic designJava 泛型设计
【发布时间】:2014-10-14 20:55:20
【问题描述】:

我有ErrorFactory 类,它基于错误代码创建不同类型错误的实例。我还有Output 类,它可能包含其中一种错误类型。

下面的代码显示了我如何尝试使用它,但不幸的是出错了。你能帮我弄清楚那里有什么问题并提出更好的设计建议吗?谢谢你的帮助!

OutputLike output = new OutputLike();
ErrorFactory errorFactory = new ErrorFactory();
int errorCode = ((Long)error.get("error_code")).intValue();
output.setError(errorFactory.<Error>getError(errorCode, error));


Error:(97, 27) java: method setError in class com.electronsoftware.VKLiker.responseoutput.output.Output<T> cannot be applied to given types;
  required: com.electronsoftware.VKLiker.error.Error
  found: java.lang.Object
  reason: actual argument java.lang.Object cannot be converted to com.electronsoftware.VKLiker.error.Error by method invocation conversion

======

public class ErrorFactory <T extends Error> {
    public <T> T getError(int error_code, JSONObject errorBody){
        Error.ErrorType errorType = Error.ErrorType.values()[error_code];

        switch(errorType){
            case CAPTCHA_NEEDED:{
                return (T) Parser.parseCaptchaRequiredError(errorBody);
            }
            case USER_AUTHORIZATION_FAILED:{
                break;
            }
            case TOO_MANY_REQUESTS:{
                break;
            }
            case NOT_ENOUGH_PERMISSIONS:{
                break;
            }
            case UNKNOWN:{
                break;
            }
        }
        return null;
    }
}

====

public class OutputLike <E extends Error> extends Output <E> {
    ....
}

public abstract class Output <T extends Error> {

    private boolean isError;
    private T error;

    public boolean isError(){
        return this.isError;
    }
    public T getError(){
        return this.error;
    }
    public void setError(T error){
        this.error = error;
    }
}

====

public static ErrorCaptchaRequired parseCaptchaRequiredError(JSONObject error){

    ErrorCaptchaRequired captchaError = null;
    ....
    captchaError = new ErrorCaptchaRequired(msg, captchaId, captchaUrl);
    return captchaError;
}

====

public class ErrorCaptchaRequired extends Error {
........
}

【问题讨论】:

  • 您应该考虑重命名这些类,Errors 是可能导致 JVM 不稳定的严重问题,例如 OutOfMemoryError。这些应该是Exceptions,而不是Errors。除非有非常好的理由,否则开发人员不应该抓住Errors。
  • 错误在他的帖子开头。
  • @Wrench 确实如此,我错过了
  • 只是转换 agument: output.setError((Error)errorFactory.getError(errorCode, error));
  • 我认为您在这里不需要泛型。 getError 应该只返回 Error。您还应该注意@JonK 关于ErrorException 的建议。

标签: java oop generics inheritance


【解决方案1】:

两个问题:

A) 您正在使用原始(无类型)ErrorFactory,它会从实例中删除所有通用信息。改为:

ErrorFactory<Error> errorFactory = new ErrorFactory<Error>();

B) 即使您修复了 A),您也输入了 getError()&lt;T&gt;,这隐藏类的类型 T
改变

public <T> T getError(int error_code, JSONObject errorBody){

public T getError(int error_code, JSONObject errorBody){

除非您真的需要输入工厂,否则我会将其设为无类型并简单地返回错误。

另外,将任何类命名为与 java.lang 类相同是一个坏主意。称之为问题或其他什么。

【讨论】:

    【解决方案2】:

    ErrorFactory errorFactory = new ErrorFactory(); 使用默认类型 Object 实例化 ErrorFactory。声明时需要说明 ErrorFactory 应该持有什么类型。

    ErrorFactory&lt;CLASSNAME&gt; errorFactory = new ...

    【讨论】:

    • 事情在 ErrorFactory 的声明中我不知道它到底是什么类型的错误。错误工厂的想法是通过仅传递 error_code 来构造我所需的错误对象。所以给定 error_code 它构造我并返回不同类型的错误。
    • 所以除了在基类型上进行强制转换之外,我没有看到其他解决方案
    • 您可以控制所有课程?可能是时候重构一些了。
    • 这个答案在解释编译错误的正确轨道上。事实上,使用原始的ErrorFactory 也会导致所有方法都被擦除。这会导致 getError 返回原始 Object,尽管有见证。 (见证人是例如&lt;Error&gt; in errorFactory.&lt;Error&gt;getError(errorCode, error)。)
    • 我确实可以访问所有类,您有什么建议可以通过重构当前模型来改进设计吗?
    【解决方案3】:

    所以基于

    并提出建议

    如果您想考虑另一种方法(经过测试和工作),这里是抽象解决方案。我们有基地

    public class ValidationError{    
       public boolean isExpected() {
         return expected;
       }
    }
    

    包含错误表示和属性。还有

    public class ScenarioError{
        public String getMessage() {
            return message;
        }
    

    }

    针对与测试场景相关的错误,因此我们会一直跟踪它们。接下来是

    public class ValidationErrorBuilder{
        public List<ValidationError> getValidationErrors(...){
        }
    }
    

    构造发现的错误。还有

    public class ScenarioErrorsContainer{
       public String getErrorMessage() {
       }
    }
    

    保留并获取以处理已发现的错误。

    当然,您必须添加一些必需/需要的接口(根据您的情况)以实现更好的 OO 设计。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-24
      • 1970-01-01
      相关资源
      最近更新 更多