Are System.out, stdout and cout the exact same thing?
Are System.out, stdout and cout the EXACT same thing in Java, C and C++ respectively?
Why have three different names for the same thing (especially when C, C++ and Java have much in common)?
Also, I know wha开发者_高级运维t they are used for but what are they exactly, under the hood, I mean?
cout
is essentially the same as stdout
but the difference is that cout
is of type ostream
(which essentially means that you can enter formatted data using <<
or unformatted data with the write
method.
stdout
is attached to a file descriptor (stdout is a FILE*
). stdout
file descriptor is 1
. Because it returns a reference to a file descriptor, it can be used in fputs
and fprintf
.
Java System.out
is essentially like stdout
(it uses java.io.FileDescriptor
with handle 1
) and passed into FileOutputStream
and finally wrapped inside BufferedOutputStream
.
This is how java.lang.System
is initialized:
/**
* Initialize the system class. Called after thread initialization.
*/
private static void initializeSystemClass() {
props = new Properties();
initProperties(props);
sun.misc.Version.init();
// Workaround until DownloadManager initialization is revisited.
// Make JavaLangAccess available early enough for internal
// Shutdown hooks to be registered
setJavaLangAccess();
// Gets and removes system properties that configure the Integer
// cache used to support the object identity semantics of autoboxing.
// At this time, the size of the cache may be controlled by the
// vm option -XX:AutoBoxCacheMax=<size>.
Integer.getAndRemoveCacheProperties();
// Load the zip library now in order to keep java.util.zip.ZipFile
// from trying to use itself to load this library later.
loadLibrary("zip");
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn));
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
// Setup Java signal handlers for HUP, TERM, and INT (where available).
Terminator.setup();
// Initialize any miscellenous operating system settings that need to be
// set for the class libraries. Currently this is no-op everywhere except
// for Windows where the process-wide error mode is set before the java.io
// classes are used.
sun.misc.VM.initializeOSEnvironment();
// Set the maximum amount of direct memory. This value is controlled
// by the vm option -XX:MaxDirectMemorySize=<size>. This method acts
// as an initializer only if it is called before sun.misc.VM.booted().
sun.misc.VM.maxDirectMemory();
// Set a boolean to determine whether ClassLoader.loadClass accepts
// array syntax. This value is controlled by the system property
// "sun.lang.ClassLoader.allowArraySyntax". This method acts as
// an initializer only if it is called before sun.misc.VM.booted().
sun.misc.VM.allowArraySyntax();
// Subsystems that are invoked during initialization can invoke
// sun.misc.VM.isBooted() in order to avoid doing things that should
// wait until the application class loader has been set up.
sun.misc.VM.booted();
// The main thread is not added to its thread group in the same
// way as other threads; we must do it ourselves here.
Thread current = Thread.currentThread();
current.getThreadGroup().add(current);
}
FileDescriptor.out
is:
/**
* A handle to the standard output stream. Usually, this file
* descriptor is not used directly, but rather via the output stream
* known as <code>System.out</code>.
* @see java.lang.System#out
*/
public static final FileDescriptor out = standardStream(1);
Source:
- cout
- stdout
- Wikipedia on
System.out
,cout
andstdout
They are the same thing, but they don't have the same type. For instance, stdout
is a FILE*
and cout
is an std::ostream
. Since C++ supports both, different names are necessary.
Under the hood, all these variables reference the standard output of the calling process. It's one of the three file descriptors (stdin
, stdout
, stderr
) that are always open by the OS when it spawns a new process. Everything written to this file descriptor ends up on the screen or wherever stdout
was redirected to (using the >
or >>
shell operators).
They are each language-specific ways for writing to the program's "standard output" file, a concept which originated with C/UNIX. They differ in the exact functions/methods they provide for performing output.
It's also worth mentioning that both cout
and stdout
are available in C++, since it halfway tries to be a superset of the C language, but mixing the use of the two may be a bad idea unless you disable buffering entirely on both. I'm not aware of any requirement for the two to share a buffer, so it's possible that output will come out misordered if you mix them.
In theory they are the same thing, all of them sent to the standard output.
But in C and C++, cout builds on top of stdout to add some features that System.out provides like formatting. Since java has no concept of pointers, System,out was redesigned to use the PrintStream to do a similar kind of task as cout.
PritnStream provides some extra features for example, PrintStream does not throw an IOException but instead sets an internal error flag that can then be accessed using checkError.
I think the naming conventions were followed because the designers of each language were different. C, C++ is closely associated with Unix and hence they used terms like standard output and console, etc. Java was designed to be more object oriented, and thus the creator of Java decided to name it a bit different.
精彩评论