Hacker News new | ask | show | jobs
by frje1400 281 days ago
> You mention "var", why would we ever want in Java to hold a variable that you can't read immediately what is the type?

var items = new HashMap();

Instead of

HashMap items = new HashMap();

That's the point of var. It reduces noise a lot in some situations.

2 comments

You should write

    Map<String, Integer> items = new HashMap<>();
It allows you to limit `items` usage to `Map` supertype and allows you to swap implementation easily, if necessary. `var` is weird feature, because it allows people to use implementation-specific methods methods and tie code to a single implementation, essentially making it less agile.

There are valid use-cases for `var`, but IMO this feature should not have been added to the language, as it's too dangerous and most people won't use it responsibly.

Your example isn’t good though; var is only for local variables, which should be perfectly allowed to use implementation-specific methods.

For argument types you don’t have var, so methods that take in a map can stay abstract and you can still pass in the implementation-specific version into those without casting it to the interface.

ETA:

I guess I am trying to say that if you want to be abstract, they should be at the argument or properties level. Local variables should be used locally. I agree that generally speaking you should try and prefer using Map for anything shared across different parts of code but I am not convinced it’s bad to have var be implementation-specific; if your method is big enough to where swapping out implementations like this will take a lot of time, your method is probably too big anyway.

No, you shouldn't write that. Your variable should represent the complete implementation. Where you use it should be as generic as possible, for example, the parameter in a function call.
Why would you want that? The whole point of an interface or superclass is to let you swap implementations without changing everything.

I also like the nudge it gives you to use only the higher level methods, rather than the ones specific to the subclass unless they're needed. That also improves flexibility.

It’s not about swapping implementations, like the original poster suggested, so that you can later come in and swap out different implementations in a local sense. Interfaces are used to decouple parts of an application; for example mocking test interfaces. Another way to look at it is that interfaces are a contract that needs to be fulfilled.

Declaring a local variable as an interface to hide functionality so you can swap out functionality later is misunderstanding the fundamental theories around interfaces. Your variable should be whatever the function or method returns. If you want to abstract the type so it can be swapped out, create a function that returns an abstract type. Don’t tell the HashMap constructor it did the wrong thing. Now that I think about it, I’d recommend you use “var” in all cases, and not try to redefine the return values from a function.

While I do use `var` when appropriate, your example is in general not appropriate

You would like to use Map<Key, Value> items = new HashMap<>() since in general you do not want implementation detail leaking into contracts

Using var there doesn’t leak any implementation details into any contracts. Var is for local variables inside of functions. There are no details or contracts there.