If I commit to returning an ArrayList then it's not backwards compatible if I want to change to a different concrete List. My experience has been that if you return a concrete class then people will rely on those details even when they don't need to. And if you're writing a library that others depend on then you don't even know how they're using your returned value.
Of course if people are doing unsafe downcasts because they need the guarantees of a particular implementation then you should just return the ArrayList directly. And fortunately this change is backwards compatible, so there's no need to worry!
If I commit to returning an ArrayList then it's not backwards compatible if I want to change to a different concrete List. My experience has been that if you return a concrete class then people will rely on those details even when they don't need to. And if you're writing a library that others depend on then you don't even know how they're using your returned value.
Of course if people are doing unsafe downcasts because they need the guarantees of a particular implementation then you should just return the ArrayList directly. And fortunately this change is backwards compatible, so there's no need to worry!