In general, it's preferred to code to interfaces (your first example, declare the variable using the interface, not the class). That way, if you need to change to a different implementation, it's trivial to do that — you just change the new to something else, and nothing else needs to change, because you code to the interface.
The reason it works is that ArrayList<BigDecimal> implements List<BigDecimal>, and so is assignment-compatible with it. That means that a variable declared as List<BigDecimal> is allowed to haev a reference of type ArrayList<BigDecimal> assigned to it. It's a design feature of the language. This is fundamental to how interfaces, and indeed OOP in general, works in Java.