Java 不推荐方法,但保留功能

Java 不推荐方法,但保留功能,java,deprecated,Java,Deprecated,假设我有一个带有抽象类的库,它有一个抽象方法: public abstract class MyAbstractClass{ public void myMethod(){ int a = doSomething("hi"); } public abstract void doSomething(String param); } 现在,我决定向该方法添加一个参数,但我希望保留旧方法的功能以保持旧代码可用: public void myMethod()

假设我有一个带有抽象类的库,它有一个抽象方法:

public abstract class MyAbstractClass{

    public void myMethod(){
        int a = doSomething("hi");
    }

    public abstract void doSomething(String param);
}
现在,我决定向该方法添加一个参数,但我希望保留旧方法的功能以保持旧代码可用:

public void myMethod(){
    int a = ?
}

/**
 * @deprecated use doSomething(String, String) instead.
 */
@Deprecated
public int doSomething(String param){ return doSomething(param, null); }

public abstract int doSomething(String param, String secondParam);
在这种情况下,我将如何实现我的
myMethod


Android支持库中的类实际上具有类似这样的结构,但另一方面:

public Object instantiateItem(ViewGroup container, int position) {
    return instantiateItem((View) container, position);
}

/**
 * @deprecated Use {@link #instantiateItem(ViewGroup, int)}
 */
public Object instantiateItem(View container, int position) {
    throw new UnsupportedOperationException(
            "Required method instantiateItem was not overridden");
}

应该阻止这种行为吗?如果我使用这个结构,我怎么知道该调用什么方法呢?

我想我看到了你的困境。您在一个库中有一个抽象类,人们正在对它的抽象方法进行子类化和实现,您希望弃用这个方法,并添加一个新的抽象方法,而应该实现它

下面是我要做的:

之前 从库用户正在子类化的
功能
类开始

public abstract class Feature {
    public abstract void doSomething(String param);
}
之后 保持
Feature
类的原样,但是不推荐该方法,并在文档中宣传人们现在应该将
NewFeature
子类化,而不是
Feature
并在该类中实现新的抽象方法。子类
Feature
的现有代码应该仍然有效

public abstract class Feature {
    /**
      @deprecated Extend NewFeature instead and implement doSomething(a, b) 
    */
    @Deprecated
    public abstract void doSomething(String param);
}

public abstract class NewFeature extends Feature {

    @Deprecated
    @Override
    public void doSomething(String param) {
        doSomething(param, null);
    }

    public abstract void doSomething(String param, String paramTwo);
}
今后
经过足够的时间后,您可以删除
功能
类。例如,我认为spring倾向于在方法第一次被宣传为不推荐使用后将其删除一个完整版本。

根据这些评论,我将做以下几点:

public void myMethod(){
    int a = doSomething("hi", "theOptimalSecondArgumentValue");
}

/**
 * @deprecated use doSomething(String, String) instead.
 */
@Deprecated
public abstract int doSomething(String param);

/**
 * Delegates to {@link #doSomething(String)} and thus ignores the second argument 
 * by default. Subclasses should override this method to return a better result,
 * taking the second argument into account
 */
public int doSomething(String param, String secondParam) {
    return doSomething(param);
}
现有的子类仍然可以工作,但处于“降级”模式,第二个参数总是被忽略

新的子类将通过以下方式实现:

@Override
public int doSomething(String param) {
    doSomething(param, "theOptimalDefaultValue");
}

@Override
public int doSomething(String param, String secondParam) {
    // compute the result using the two arguments
}

旧代码如何可用?你引入了一个新的抽象方法,打破了所有现有的子类。为什么你不能继续调用
doSomething(“hi”)
(带有抑制警告)或者只调用
doSomething(“hi”,null)
?你可以在
myMethod()
@JBNizet-Hmm中调用新的
doSomething(String,String)
,真的。因此,最好的方法是删除
abstract
关键字,并抛出一些错误,表示需要重写该方法?@JonSkeet我想添加一些额外的数据供实现者(可选)用于计算结果。这看起来确实是理想的方法。我可以检查该类是否是
NewFeature
的子类,以决定调用哪个方法。事实上,我不需要在
doSomething()
NewFeature的
doSomething()方法中调用
doSomething(param,null)
,因为它无论如何都不会被调用?是的,当然-任何真正有意义的东西。没有一个具体的例子很难说。虽然这会起作用,但我认为这会给实现者带来一些困惑。正在弃用该方法,但仍要求重写该方法。