Pergunta

I have to work with an older Interface specifying methods with bare List parameter.

void updateParameter(List param1, List param2);

Obviously I need to implement them with the same signature.

@Override
public void updateParameter(List param1, List param2) {
    updateParam1( param1 );
    updateParam2( param2 );
}

But what about new code? Should I keep working with these old Lists. Should the new method's signature take generic Lists?

private void updateParam1( List<String> param1 ) { ... }

Should I explicitly convert/cast them?

What are the best practices here?

Foi útil?

Solução 2

I personally stick to the philosophy of "Don't let defects get passed down stream". Somewhere, an unsafe type cast MUST happen (even if it is done under the hood by the compiler). Why not do it as early as possible? That way the code downstream can be clean and you only have the problem in one place instead of scattered throughout your code base. This also follows the principle of "fail fast".

@Override
public void updateParameter(List param1, List param2) {

  List<String> param1TypeSafe = (List<String>)param1;
  List<String> param2TypeSafe = (List<String>)param2;
  updateParam1( param1TypeSafe );
  updateParam2( param2TypeSafe );
  //now nowhere else in the codebase needs to deal with it.
}

Outras dicas

You are correct about writing the new code with generics (considering how long ago generics became available, the switchover is long overdue). The most explicit approach to the switchover is deprecating the old interface, defining a new one, implementing both interfaces in your classes, making all implementations of the old methods thin wrappers around the new methods. Here is an example that assumes the updateParameter is the only method in the old interface:

interface OldInterface {
    @Deprecated
    void updateParameter(List param1, List param2);
}
interface NewInterface {
    // Change the name
    void updateParam(List<String> param1, List<String> param2);
}
class NewClass implements OldInterface, NewInterface {
    public void updateParameter(List param1, List param2) {
        updateParam((List<String>)param1, (List<String>)param2);
    }
    public void updateParam(List<String> param1, List<String> param2) {
        ... // The actual implementation goes here
    }
}

Over time, you will be able to get rid of the old interface. By then, all you would need to do is removing the methods, which are already deprecated.

Generics in Java were designed to be backwards compatible. So, you can pass List < String > and List < Integer > objects in as parameters to your legacy methods. You don't have to explicitly cast them.

Best practice - use generics in all of your new code for added type safety. Where you are forced to plug in to legacy code, just pass them in as parameters without any conversion. You will have to be careful with any collections received back from the legacy API - here it would be appropriate to check the type of objects returned.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top