| Home > Core Java FAQ
> Language Fundamentals FAQ |
| Java
Fundamentals |
| Basic(19) * Constants
and Expressions(40) * Variables and Methods(16)
* Array(11) * Date/Time(36)
* Compile Time(11) * Run
Time(02) * C-vs-Java(12) |
| |
|
Q . Why doesn't my "Hello World!" program compile?
|
Ans :
There are three basic possibilities:
1. Are you successfully running the javac compiler? Try
javac -garbage
to see if it prints out a message about correct usage. If not, invoke javac using the full pathname, or set your PATH variable to
include the directory that contains javac.
2. Is the CLASSPATH environment variable used correctly?
In JDK 1.0.2, beginners had to set CLASSPATH, and it had to include both system libraries and your programs.
In JDK 1.2, CLASSPATH is no longer needed for system libraries. You do want CLASSPATH to point to the directories containing any
"user classes" you're using. Getting started, you will probably want at a minimum "." (the
current directory) in your CLASSPATH. When CLASSPATH is wrong, javac will tell you it can't find
definitions for classes you reference in the source file. For information on setting up the CLASSPATH, see Question 1.3
3. Is the source correct?
Here javac will emit error and warning messages. See the questions on compiler messages in the next section.
|
|
Q .
Why do I get a "Statement not reached" error from javac for no apparent reason?
|
Ans
:
JDK 1.0 has a limit of 63 words of storage for local variables in
any method. longs and doubles require two words of storage, and all
other primitive types and all reference types require one word. If you
assign values to more than 63 words of local variables, you will get a
"Statement not reached" error on the statement after you assign to the
variable that contains the 64th word. In JDK 1.1, the low limit was
removed.
|
|
Q .
Type expected {public method variable}
.. .. ?
|
Ans
:
public static void main(String[] args) {
^
Statement expected.
public static final float Conversion_Factor = 39.37;
^
Type expected.
Argument and variable declarations inside methods are never public or static because they are local to a method. (Before JDK 1.1 they
couldn't be final either, but there was no good reason for that restriction and it was dropped.) If you have public or static
variables, move them outside the method. They are usually put at the
beginning of the class.
|
|
Q .
Can't access protected method clone in class java.lang.Object
.. .. ?
|
Ans
:
T.java:96: Can't access protected method clone in
class java.lang.Object. OtherT is not a subclass of
the current class.
Object.clone() is protected because subclasses might want to restrict access to cloning, and if Object.clone() were declared public,
subclasses could never make it more restrictive. The subclass can make
access to the clone() operation less restrictive. This means that a method can clone its own objects, but a method cannot
clone objects of another class, unless you do something like:
class SomeObject implements Cloneable {
public Object clone()
throws CloneNotSupportedException {
return super.clone();
}
}
i.e., override clone() to make it public, and call the superclass clone().
class Foo {
Bar bar;
Foo (Bar b) {
try {bar = (Bar) b.clone();}
catch (Exception e) {}
}
....
class Bar implements Cloneable {
public Object clone()
throws java.lang.CloneNotSupportedException {
return super.clone();
}
}
Another refinement is to note that Object.clone() only throws a CloneNotSupportedException when the object doesn't implement
Cloneable. Since you control what your classes do and don't implement, you can
ensure that Cloneable classes implement the interface, and you don't
need to make the overridden clone() throw the exception.
public class X implements Cloneable {
public Object clone() { // no throws
try {
// in case members need cloning
X c = (X)super.clone();
return c;
} catch (CloneNotSupportedException e) {
// should not happen, because of Cloneable
throw new InternalError();
}
}
}
|
|
Q . What does "deprecated" mean? I got this in a compiler error message.
|
Ans : "Deprecated" means you are using an older API, that Sun has
replaced with a newer one (usually to follow more consistent naming conventions). Deprecated methods are not recommended for use. They are
supported in the short term, but your code should be updated with the
new. To update your code, compile your old code using javac's "-deprecation" option to list deprecated methods, then find the
replacement methods in the current HTML API documentation for the old deprecated methods.
As an example of a deprecated API, Component.size() was replaced by
Component.getSize().
See also
1.1 Deprecated
Methods
and
Deprecated methods in the 1.1 AWT
|
Q . double y = sin(90);
What's wrong? That code provokes compiler messages.
|
Ans
:
You need to write it this way:
double cvtDegToRad = Math.PI/180;
double x = 90*cvtDegToRad;
double y = Math.sin(x);
sin is a static method of the Math class that takes radians. You need to use the "Math" classname, e.g. Math.sin instead of plain sin,
because you have to say what class or object these methods belong to.
A very common mistake is to assume that importing a class means that you don't have to qualify the names of its members. When you call a
method you have to state the name of the class or object it belongs to,
regardless of any imports you have done. (Except inside the class itself, obviously).
The trig functions are static methods of the Math class, so you give the name of the class in invoking them. Further, the Math class works
in radians, not degrees. 360 degrees = 2 pi radians, so use a conversion factor as shown if you are working with degrees.
|
|
Q . Incompatible type for =. Explicit cast needed...
|
Ans
:
byte b = 0;
Incompatible type for =.
Explicit cast needed to convert int to byte.
b = b + 100; // compiler error message
b += 100; // works OK
Arithmetic expressions are promoted to the type of the longest, floatiest operand in them, or at least to int. The first statement
involves the assignment of an expression. The expression is promoted to
32 bits, and must be cast back down to 8 bits, like this: b = (byte)
(b+100); The second is an operator assignment, and the cast back to
byte takes place automatically. The Java Language Specification says
that a compound assignment expression of the form E1 op= E2 is equivalent to E1 = (typecast)((E1) op (E2)), where "typecast" is the
type of E1, except that E1 is evaluated only once. (See JLS 15.25.2
Compound Assignment Operators) The compile-time narrowing of constants
means that code such as:
byte theAnswer = 42;
is allowed, with no cast necessary.
|
|
Q . Class {package}.{class} not found in type declaration.
|
Ans
:
I am trying to compile file "{class2}.java" in a package, and I get
this compiler error. {class2}.java refers to {package}.{class}, but the
file {class}.java and {class2}.java are in the same {package}
directory, which is the current directory and which is in the CLASSPATH variable. Both files have "package {package};" at the top of the file.
What's the problem?
When the source refers to classes in packages, the CLASSPATH has to point to the root of the package/directory hierarchy for a reference to
resolve correctly. This is true even for source files in the same package (and directory). I.e., assuming {class} and {class2} are both
in {package}, {class} can't make a reference to {class2} unless the
CLASSPATH is set so javac can find {package}/{class2}.java. It should
make no difference what directory you are in when you invoke javac,
unless you are relying on "." in the CLASSPATH to point to the package
root or are specifying the source file with a relative path (e.g.,
{package}/{class}.java).
Some examples, assuming
o - Foo.java and Bar.java are in /java/source/pack/
o - Both have "package pack;" as the first statement
o - Foo.java includes "Bar b = new Bar();"
# solaris ksh
$ alias jc=/java/jdk11/bin/javac
$ CLASSPATH=/java/source/
$ jc /java/source/pack/*.java # works fine
$ cd /java/source/pack
$ CLASSPATH=.
$ jc *.java # fails - Foo.java can't find class Bar
$ cd .. # now . is package root, /java/source/
$ jc pack/*.java # works
|
|
Q . public class "Foo" must be defined in "Foo.java" I get this message even though it is in Foo.java. What gives?
|
Ans
:
Javac verifies that a public class is defined in a file of the same
name (e.g., that public class Foo is defined in Foo.java). Two things
you can check:
First, make sure the case matches exactly. public class Foo cannot be in foo.java; it has to be in Foo.java.
Second, are you using MKS on win32? Javac on win32 assumes you are using the DOS path separator (\) even though MKS accepts the Unix path
separator (/). When javac tries to parse a your Unix-style path, it
won't produce the correct filename, the match will fail, and it will
emit an error. You have to use the DOS path separator (\), which must
be escaped in MKS
- e.g.,
"javac H:\\source\\package\\Foo.java".
Alternatively, you can traverse to each source directory and avoid pathnames altogether.
|
|
Q . What does "deprecated" mean? I got this in a compiler error message.
|
Ans
: The compiler will flag a now-obsolete API as "deprecated". The word
means "officially disapproved of". Compile again with the "-deprecation" option to see what is deprecated. In almost all cases,
the old API has been replaced by a new one. Update your code to use the new one.
An example of using a deprecated API is calling component.size(). That has been replaced by
component.getSize().
|
|
Q . Why can't the compiler find my package?
|
Ans
: When trying to compile a file in a package you get a compiler error
like:
DBTest.java:10: Class database.Table not found in type declaration.
The file Table.java and DBTest.java are in the same directory. They both have "package database;" at the top of the file. The current
directory is included in the classpath.
The reason is that when compiling packages, you have to be at the 'top' of the directory/package hierarchy. So to compile both Table.java and
DBTest.java, you have to be in the directory that contains the database
directory (i.e. where the package hierarchy starts), and just:
javac database/Table.java
javac database/DBTest.java
and it should all compile fine.
|
|
|