For reference types, upcasting is implicit (or at least what I think you mean by implicit—that's not standard Java terminology). There is no implicit down-casting. So if you have Superclass base class and a Subclass class that extends Superclass, you can do this:
Subclass a = new Subclass();
Superclass b = a; // no cast needed.
However, for this:
Superclass a = new Subclass(); // no cast needed
Subclass b = (Subclass) a; // cast required
Note that in general you are at risk of throwing a ClassCastException when you downcast unless you can guarantee that the downcast will work. This is typically done by using the instanceof operator:
Superclass a = new Subclass(); // no cast needed
Subclass b;
if (a instanceof Subclass) {
b = (Subclass) a; // cast required
} else {
// handle problem of a being a different subtype of Superclass
}
The standard terminology for upcasting is widening and for downcasting it is narrowing the type.
EDIT (based on edit to question):
I don't know what those posts you cite mean, unless it's the following. In Java, all reference type variables are just that—references. All that's happening when Java executes:
Subclass b = (Subclass) a; // cast required
is that it is assigning the reference stored in a to b after first checking that the object referenced by a is assignment-compatible with the declared type of b. (Note that the above does not mean that the object is of the same type as b—it could be a subtype.) The object itself is not converted in any way to a new object structure. Any changes you make to the internals object through b will be seen if you then access the object through a (provided the changes affect the more abstract view of the object represented by a). In a sense, a and b are aliases (usually with different public apis) to the same object.
You will get a run-time error if the compatibility check fails. You will get a compile-time error if the check could not possibly succeed. Thus, you cannot get this past the compiler:
String x = "Hello world";
Integer y = (Integer) x; // compiler error
The aliasing described above does not happen when casting primitive values—such as from int to long. In those cases, Java will generate a new copy of the value in the machine representation of the cast type.