Using the terms used in that slideshow - a literal is kind of container, so it'll be better to compare between values and containers.
A container "contains" a value. If you write int x=1;
, then x
is a container and the number one is a value. But 1
is also a container - more precisely, a literal. The slideshow stress that there is a difference between the value one and the literal 1
.
When you code, you can't actually access values directly - you can only do it via containers. That's why you can write x
and 1
, but not the value that is the number one.
A literal is a container that can be translated directly to a value without looking at it's surrounding - for example 1
can be translated directly to the number one. x
can not be translated to a value in such a way, since it's a variable and we don't know what it holds unless we look at the surrounding code.
As for the dynamic vs static types - a container has a static type, known at compile-time. If it's a variable, it's the declared type of the variable. If it's an expression, it's the inferred type of the expression. If it's a literal, it's the direct type of the literal. The compiler can tell the type of each container without running the program and without caring what values it'll hold once the program runs.
A value, on the other hand, is stored in memory as a series of bytes. The type data is also stored in memory near the value(unless it's a primitive value), that's why the types of values are dynamic - because if you want to discover what type a value has, you have to look in the memory during runtime.
Even though values' types are dynamic, Java is a static language since you usually don't look at the dynamic type. Since you can only refer a value via a container, the static type of the container is used when you do things with the value.