I'll try to explain it in more detail.
Each
Java class belongs to a certain package. The reason is twofold. First, related classes can be bundled together, and have more access to each other than classes outside the package do. Secondly, a package is also a name space, so you can distinguish two different classes that happen to have the same class name. For instance, java.util.List is a different class than java.awt.List.
The fully qualified name of a class is its package name followed by its class name. java.util.List is a fully qualified name, it specifies both the package and the class name.
You don't need import statements to use other classes! You can always use another class by using its fully qualified name. However, this can get very tedious and distract the reader from the meaning of a program. The *only* thing that import statements do, is make it so you don't have to use fully qualified names when you're frequently using a class. If I import java.util.List, or java.util.*, I can use List anywhere in the following code, and the compiler will know it's a reference to java.util.List.
Java automatically imports classes from the java.lang package, and from the same package as the current class. If B and MyClass were both in the com.foo package, you still wouldn't need the import statement, because the compiler will automatically import the com.foo package for the B and MyClass source files.
Now let's move on the class paths. The javac compiler compiles source files to class files. You specify the path of the source files you wish to compile. This location is independent from the class path. You either specify an absolute path, or a path relative to the working directory. However, the compiler still needs to know the location of classes you reference from your source code, so it can do proper checking. It finds these relative to the class path, not the current working directory.
In your example, B belongs to the default package, and is located at C:\...\myProject\B.java. MyClass belongs to the com.foo package, and is located at C:\...\myProject\com\foo\MyClass.java.
What happens when your current directory is C:\...\myProject\ and you run javac B.java is the following: The compiler finds B.java relative to the working directory. It finds the source file and attempts to compile it. It finds a reference to MyClass so the compiler needs to figure out which MyClass it is. It first looks for com.foo.MyClass, MyClass and finally java.lang.MyClass. It looks for com.foo.MyClass relative to the class path. Since you didnĀ“t specify a class path, the class path defaults to the current working directory. The compiler looks for a definition of com.foo.MyClass at C:\...\myProject\com\foo. It will find either MyClass.java or MyClass.class, either will do.
So what happens when you remove import com.foo.*; from B.java? The compiler will then try to look for MyClass in the default package, and in the java.lang package. It doesn't find a definition of MyClass in the working directory, nor in a folder java\lang\ relative to the working directory, so compilation fails.
Now we also remove package com.foo from MyClass and specify
-classpath com/foo. The compiler finds B.java because you *explicitly* tell the compiler which file to compile, relative to the working directory. The class path never influences this. B references MyClass, and the compiler looks for it in the default package and in java.lang. It does this relative to the class path. The default package here is C:\...\myProject\com\foo, because that's where you said it would be in the class path. The compiler finds a definition of MyClass here, so it's happy.
Note that if the compiler was looking for a class named com.foo.MyClass, and you had set the class path to com\foo, it would have looked for the class at C:\...\myProject\com\foo\com\foo.