| 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 . How Do I Call C Code from Java?
|
Ans :
First of all for security reasons you can only call external code from an application. You cannot call external code from an applet. (Otherwise all the security would go out the window.) Furthermore all code you write in this way will be non-portable. If these aren't problems for you, check out javah in the JDK 1.0 or the Java Native Interface in JDK 1.1.
|
|
Q . How Do I Call Java from C?
|
Ans
: Since Java is not as of yet a true compiled language, the only way to call Java code from C in Java 1.0 is by using the system() call (or your OS's equivalent) to execute the java interpreter with appropriate command line arguments.
In Java 1.1 the Java Native Method Interface in combination with the Invocation API allows native applications to load and access the Java virtual machine.
|
|
Q .
How do I call the native API from Java?
|
Ans
: You can do this only in an application, not in an applet. You will need to write some intermediary code in C or another traditional language and call your C code from Java.
|
|
Q . How do I translate C/C++ into Java or vice-versa?
|
Ans
: In general it is not simple to translate C/C++ into Java, as Java
lacks the arbitrary pointer arithmetic of those languages. If your C
code does not use pointer arithmetic, automatic translation gets a lot
simpler. Try these URLs:
http://www.ist.co.uk (search for X-Designer 4.6: Java edition).
http://members.aol.com/laffra/c2j.html
http://www.ilog.com/
Going the other way there are currently three freely-available tools to translate Java into C. It seems that these have been done for hacking
value, rather than practical purposes.
o
j2c from
Japan
o Toba from the Sumatra research project, translates 1.0.2 .class
files into .c source code
o JCC from Nik
Shaylor.
None of them support the AWT yet, and both j2c and JCC have additional restrictions.
There's a product to convert Visual Basic to Java. Details at
http://www.blackdirt.com and http://www.javadelphi.com (also a Delphi-to-Java source converter)
and http://www.tvobjects.com
There's a product to translate COBOL source to Java source, see
http://www.Synkronix.com/
This program dumps info about the class file:
http://www.professionals.com/~cmcmanis/java/dump/index.html
Chuck McManis was one of Sun's original Java implementors.
|
|
Q .How are finalizers different from C++ destructors?
|
Ans : Java objects are not explicitly deleted and do not have
destructors. Instead they are implicitly garbage collected when the JVM
realizes your program can no longer access them. Typically this
technology is _not_ based on reference counting and _will_ cope with circular references.
Every object has a routine called finalize() which will be called before the object is collected. This is Java's nearest equivalent to
C++'s destructor. However, it is not a good idea to rely on finalization for the timely freeing of resources.
This is because garbage collection and hence finalization may be arbitrarily delayed, and may never happen at all if the program
terminates before it runs out of memory. You should instead provide
your objects with methods similar to Graphics.dispose() to free resources, and call the dispose() method explicitly when you have
finished using them - typically within the "finally" clause of a "try/catch" block. You may then call your dispose() method from within
your finalize() method as a last-ditch attempt to free the resource if
someone forgets.
Alas, all this means the C++ idiom of "object construction is resource
aquisition" does not translate well to Java. However, note that 90% of
destructors in C++ are there to free memory, and the GC means you don't
need to do that in Java. As well as fixing an important source of bugs,
the GC is essential to Java's security model; without it you could forge object references by preserving the reference after the object
has been deleted.
If your program appears to be crashing due to running out of some system resource (like File, Window or Graphics handles), it probably
because the system is running out of handles before it has run out of
memory. Check that you have called the dispose() method (or equivalent) on every object that uses system resources. You can help the GC a
little bit more by explicitly NULLing out references that you've
finished with.
|
|
Q . What's the Java equivalent of sizeof()?
|
Ans
:
There isn't one. sizeof() in C and C++ is used in three main
places:
1. To check on the size of a primitive type. In Java, the sizes of primitive types are fixed in the language specification (a short
is _always_ 16 bits; an int is _always_ 32 bits, etc), so this is no longer necessary.
2. In memory allocation (i.e. malloc (32 * (sizeof(int));) In Java you always allocate a specific type of object, rather than a block
of raw memory that you will fill as you like. The system always knows the size of the kind of objects you are allocating. So
sizeof is not needed.
3. In pointer arithmetic (i.e. p += sizeof (int)) Pointer arithmetic of this type is not allowed in Java, so this isn't necessary,
either.
For all these reasons, there is no need for a Java sizeof() operator. Some people have suggested that you can find out the size of an object
by having the object serialize itself to a ByteArrayOutputStream, and
looking at the bytearray.length.
That won't work because a lot of additional data is written when an object is serialized. The additional data includes a description of the
class, any objects referenced by the serialized object, null references
(written as a single byte), etc. If you write another instance of the same class, the amount of data written can differ dramatically. And if
you serialize the same object again, it isn't written at all -- even if
its data fields have changed! Instead, a one byte token and a four byte
"sequence number" that refer to the first writing are output. Using
Object Serialization to determine the size of an object does not (except by coincidence) give the right answer.
|
|
Q .Does Java have the equivalent of "const" arguments in C and C++?
|
Ans
:
Java 1.1 adds the ability to use the "final" keyword to make
arguments constant. When used to qualify a reference type, however,
this keyword indicates that the reference is constant, not that the
object or array referred to is constant. For example, the following Java code:
void foo(final MyClass c, final int a[]) {
c.field = 7; // allowed
a[0] = 7; // allowed
c = new MyClass(); // final means this is NOT allowed
a = new int[13]; // final means this is NOT allowed
}
is roughly equivalent to the following C/C++ code:
void foo(MyClass * const c, int * const a) {
c->field = 7; // allowed
a[0] = 7; // allowed
c = new MyClass(); // const means this is NOT allowed
a = new int[13]; // const means this is NOT allowed
}
Java does not have any equivalent to the following C/C++ function declarations:
void foo(const MyClass *c); // a pointer to a const class
void foo(const int *a); // a pointer to a const int
void foo(const int a[]); // a pointer to an array of const ints
|
|
Q .
How can I write C/C++ style assertions in Java?
|
Ans
:
The two classes shown below provide an assertion facility in Java.
Set Assert.enabled to true to enable the assertions, and to false to
disable assertions in production code. The AssertionException is not
meant to be caught--instead, let it print a trace. Since the exception
is not meant to be caught, we just extend Error instead of
RuntimeException. As with RuntimeException, a method does not need to
declare that it throws Error. In addition programmers are less likely to write "catch(Error) ..." than "catch(RuntimeException)".
With a good optimizing compiler there will be no run time overhead for many uses of these assertions when Assert.enabled is set to false.However, if the condition in the assertion may have side effects, the
condition code cannot be optimized away. For example, in the assertion
Assert.assert(size() <= maxSize, "Maximum size exceeded");
the call to size() cannot be optimized away unless the compiler can see that the call has no side effects. C and C++ use the preprocessor to
guarantee that assertions will never cause overhead in production code.
Without a preprocessor, it seems the best we can do in Java is to write
Assert.assert(Assert.enabled && size() <= maxSize, "Too big");
Alternatively, use
if (Assert.enabled)
Assert.assert( size() <= maxSize, "Too big" );
In this case, when Assert.enabled is false, the method call can always be optimized away totally, even if it has side effects. The relevant
sections of the JLS are Section 13.4.8, final Fields and Constants and
Section 14.19, Unreachable Statements. 13.4.8 requires that primitive constants ("a field that is static, final, and initialized with a
compile-time constant expression") be inlined. So everywhere Assert.enabled is refered it is replaced at compile time with its
value. Writing:
if (Assert.enabled) Assert.assert(size() <= maxSize, "Too big");
is exactly the same as writing:
if (false) Assert.assert(size() <= maxSize, "Too big");
... assuming Assert.enabled is false at compile time. Section 14.19 discusses compiling away such dead code. To sum up: the inlining of the
primitive constant is required by the spec. The subsequent optimization
of not generating code masked by (what turns into) an "if (false) ..."
is not required but is implemented by many existing Java compilers.
public class AssertionException extends Error {
public AssertionException(String s) {
super(s);
}
}
public final class Assert {
public static final boolean enabled = true;
public static final void assert(boolean b, String s) {
if (enabled && !b)
throw new AssertionException(s);
}
}
|
|
Q . How do I do stuff like scanf and sscanf in C/C++? And how do I do stuff like
sprintf?
|
Ans
:
float x = 12345.6789;
printf("%6.3f/n", x);
You can break a string like "5 loaves 2 fishes" into its parts by using java.util.StringTokenizer. This is the Java equivalent of
sscanf().
StreamTokenizer does a similar thing on a file or any stream (i.e, what
scanf() and fscanf() do in C).
To do formatted character output, create a format string, and then use that to format your binary value, e.g.
import java.text.*;
float fi = 1234.56789F;
DecimalFormat mydf = new DecimalFormat( "###0.000" );
mydf.setMinimumIntegerDigits(3); // for example
System.out.println( mydf.format(fi) );
gives:
1234.567
If you want to see a float print out as "0.0000001" instead of "1E-7", use:
java.text.DecimalFormat myFmt = new
java.text.DecimalFormat("#,###,###,###.############");
System.out.println(myFmt.format(myFloat));
There are lots of different characters you can feed to the DecimalFormat constructor, not just "0" and "#". See
$JAVAHOME/src/java/text/DecimalFormat.java source for details.
The always excellent Acme site has an sprintf() package written in Java See
|
|
Q . What is the Java equivalent of C++'s "friend"?
|
Ans
: The keyword "friend" in C++ is a hack to allow a piece of code to
access the private member declarations of another class. In Java, you
would do this by labelling, not the friend, but the private members.
Instead of making them private, make them either protected or package
(no keyword) or public.
The four different Java protection levels are: private, package, protected, and public.
1. private members can only be accessed by the containing class and
internal classes.
2. package (specified by omitting other keywords) is the default level of protection; members are accessible from any class within
the package of the containing class.
3. protected is package-level-access plus access to sub-classes of
the containing class. So "protected" is less protected than the default.
4. public fields in public classes are accessible from all classes.
|
|
Q .
Does anything like the C++ Standard Template Library exist for Java?
|
Ans
: Yes, only it's better and simpler to use in Java. It's called the
Java Generic Library. This library (JGL) is freely downloadable from
http://www.objectspace.com/
It includes about a dozen nice data structures (including sets and bags) and algorithms like unions, searching, and sorting.
It has over 100,000 users and 11 OEM distributors. [Some Java vendors are bundling it with their next release]
|
|
Q .
What happens to post-increment when an exception is thrown?
|
Ans
: If you have the code:
array[i++] = foo();
and foo() throws an exception, i will be incremented anyway. This can cause problems if sometimes foo() throws an exception and you don't
want i incremented in cases when it does.
This is a consequence of JLS 15.25.1 and 15.6.1 "the left-hand operand of a binary operator appears to be fully evaluated before any part of
the right-hand operand is evaluated." (assignment is taken as a binary
operator). Note that this is not how C++ behaves.
|
|
|