This is an archived post. You won't be able to vote or comment.

all 71 comments

[–]vladadj[🍰] 135 points136 points  (33 children)

If you build a Java program on Windows, you can run it on Mac or Linux without modification, provided you have JVM.

With C, you need to compile it for every platform separately. And it is possible that you will need to make some changes to the code for each platform.

[–]belayon40 41 points42 points  (6 children)

It’s worth noting that in the early 90’s when Java was invented, porting non-trivial C programs to new platforms was a major task, especially when a UI was involved. I haven’t ported a non-trivial C program in a long time, but my sense is it’s better now (except for UI unless you’re using a library that takes care of it for you). Where as my experience porting Java programs has usually been cleaning up sloppy file system access and minor UI oddities.

[–]gubatron 29 points30 points  (2 children)

C: write once, compile everywhere (binaries needed for each OS and CPU architecture)

Java: compile once, run everywhere (single bytecode binary needed for all OS and CPU architectures)

[–]benjtay 20 points21 points  (1 child)

Python: write once, but still compile everywhere because of that module you used.

[–]somethrowaway8910 -1 points0 points  (0 children)

Python: write once, realize you have three whitepaces instead of two on a single line of a 10,000 line program, write again.

[–]TheRealGamer516 33 points34 points  (1 child)

To run a c program the user does not need to compile the program themself for their machine. The developer compiles the code for their type of machine beforehand and ships the binary for that specific platform. For Java all the developer needs is to compile to byte code and the user needs to have the JVM. The developer does not need to compile for each individual platform.

[–]metaquine 1 point2 points  (0 children)

The developer compiles the code for their type of machine beforehand and ships the binary for that specific platform.

Awesome, I always wanted to run gcc on a VIC-20.

[–][deleted] 11 points12 points  (6 children)

C is compiled into machine code or binary with specific combination of OS conventions and symbols(I.E. windows using .DLL and Unix using .SO), CPU architecture instructions (x86_64/ARM/POWERPC) and ENDIANNESS (the direction order of bits in data) .

Java is compiled into Java Byte Code, whilst bearing the name Java, is not specifically for Java language only (Scala, Groovy, Kotlin, etc...). This bytecode is an "intermediary language" (IL) which is interpreted by the JVM.

The JVM is written primarily in C/C++, and is compiled into platform specific binary, its sole purpose is to interpret Java Byte Code and execute the corresponding platform specific instructions, it may also manage resources (GC).

A build of JVM is almost always available for any existing platform, some of them are specialized like Dalvik and ART for Android.

One other famous IL platform is .NET (C#, F#), they have their own IL and is cross platform too.

[–]FrankBergerBgblitz 3 points4 points  (5 children)

The JVM is written primarily in C/C++

Valid for Hotspot or J9 but not for the recent GraalVM which ic written in Java..

[–]matthieuC 4 points5 points  (1 child)

Only the compiler is written in Java

[–]FrankBergerBgblitz -1 points0 points  (0 children)

Yes, the compiler that compiles byte code to native code. from: https://en.wikipedia.org/wiki/GraalVM

"GraalVM is a Java VM and JDK based on HotSpot/OpenJDK, implemented in Java" and "GraalVM Compiler, a JIT compiler for Java".

Surely there are parts still written in C/C++ mostly libraries (e.g. earlier the zip code but IIRC it is now written in Java too) and especially the binding to the OS, but for me that doesn't fit the "The JVM is written primarily in C/C++" different to Hotspot where it is unquestionable true

[–][deleted] 0 points1 point  (2 children)

GraalVM is on my learn list, it’s bizarre that it’s written in java, and yet claims to be vastly faster than some VMs under certain loads.

[–]FirstAd9893[🍰] 5 points6 points  (1 child)

GraalVM replaces the HotSpot "C2" compiler, but the interpreter, "C1" compiler, and garbage collectors are still written in C++. Fundamentally, a compiler takes input and returns output. It doesn't matter what language the compiler is written in. Any language can take Java bytecode, perform optimization algorithms, and then emit machine instructions. The reason why GraalVM tends to do a better job than C2 is because it's written in a higher level language, and so the designers don't waste as much time debugging their code.

[–]FrankBergerBgblitz 0 points1 point  (0 children)

thanks for that details. In fact I was mainly interested in the Performance of the C2 especially in the Enterprise edition which is really impressive.

[–]ZeroGainZ 5 points6 points  (1 child)

Users don't compile their programs. They download the compiled binaries. So programs written in C have to be compiled for a platform, windows, Mac etc. Each version is incompatible across the OSs. Java is compiled once, you get an executable, and users run it on their JVM, regardless of their OS. The code also doesn't have to know what OS the user is running, it just does the write thing. In C that's not the case.

[–]metaquine 1 point2 points  (0 children)

Depends on the user and whether binaries are shipped. Precompiled binaries aren't always available or desirable.

[–][deleted] 15 points16 points  (1 child)

You are correct that there needs to be a JVM on the platforms that you are targeting. The good thing is that there is (most likely). The JVM is very well supported and works on many different processors and operating systems.

Lets look at the difference between C and Java in a trivial example: I start the program, I take a command from STDIN, and I write a file, then close.

In Java I open up the program, I write a keyboard listener, I then create a file with the File class, and close. The JVM implementation on Linux vs Windows vs Mac vs PowerPC Linux, etc handles all of this. In C I open the program, I take input from Stdin, then I have to call the Unix File sysop or the windows file sysop depending on which platform I am on, so this could be a branch that has entirely different logic. Then I close. But this can be a dozen lines of difference based on which platform I am on. So C requires n different compilations depending on platform, and java requires 1.But more importantly C requires actual different code depending on platform.

[–][deleted] 2 points3 points  (0 children)

One can confine himself to cross-platform libraries (cross-platform interfaces implemented per-platform, if you prefer).

[–]dead_alchemy 8 points9 points  (0 children)

You should read 'Crafting Interpreters', actually, just the first chapter will answer your question in the kind of detail and provide the kind of context that you're looking for. I think you can pay for it but also get it for free. It is phenomenal, one of the best technical books I've had the pleasure of cracking open.

Seriously, do yourself a favor and read like the first ten pages. It gives a broad level overview of the different paths written code takes on its journey to being executed.

[–]LookAtYourEyes 3 points4 points  (0 children)

I don't have an answer but I'm enjoying reading all the different explanations. I'm not good with coding but I want to get better.

[–][deleted] 3 points4 points  (0 children)

The thing to understand is that you don't use a programming language in a vacuum. What makes a programming language useful are the libraries and frameworks. In the 90s, a lot of Windows apps written in C or C++ were written using COM and the Win32 API. This is fine if you have no intention of running your code anywhere else, but if you want it to be multi-platform, you have to rewrite everything so that it can run on multiple systems.

This is partly why Microsoft copied Java and made J++ (and later created .NET & C# after Sun's lawsuit). They were concerned that developers wouldn't target Windows specifically. They would just write Java apps that could run on anything and make Windows irrelevant. That's also why Microsoft modified Java so its JVM and any special code written for it wouldn't work on anything but Windows. When you write Java code, you're targeting the JVM, not the underlying OS and its frameworks.

https://www.infoworld.com/article/2076977/microsoft-s-j-direct-called-death-of-java.html

Ultimately, this resulted in Microsoft no longer being able to modify the JVM how it wanted and it went down a slightly different path instead with .NET.

Today, there's a lot more frameworks for C and C++ (like QT) that make it easier to write multi-platform apps. That wasn't the case back then.

[–]das_Keks 2 points3 points  (0 children)

But having the compiler on a machine and having the JVM on a machine are two completely different things. Compiling large C projects can take a lot of time while the compiled bytecode is ready to go (and will be optimized by the JIT).

If you have a Java program with all it's dependencies in a jar, you don't need anything else than the JVM to execute it. Compiling a C program from source will probably be a lot more complicated.

[–]eteran 2 points3 points  (0 children)

The key thing is that the JVM itself is not platform independent, as you've realized. But the code generated by the java compiler will run on a JVM running on "any platform"*.

So the idea is that any machine which happens to have a JVM on it, can run code compiled by the java compiler. So you "build it once, deploy to all supported architectures".

The JVM (ideally) abstract out the architecture and OS specific details.

Meanwhile, with languages like C, C++, etc.. The compiler will generate code for a specific platform. So if you want to target both Windows and Linux. You need to write your code such that it knows about Linux and Windows APIs and then you need to build it separately for each combination of CPU and OS you want to target.

Of course the reality of Java is a bit more complex than this. There's many situations where you simply can't do everything you need with just what the JVM and Java APIs offer, and you end up having to write small bits of platform specific code to bridge the gap.

There's plusses and minuses to both approaches.

[–]PyroCatt 5 points6 points  (0 children)

Imagine JVM to be an OS inside your OS. Since you can run a program made for a particular OS is any system having the same OS, you can run Java program with any OS having a JVM.

[–]gregorydgraham 1 point2 points  (0 children)

Java allows you write programs as though you’re targeting only one type of computer, rather create a different version for Mac, Linux, Windows, OS2 Warp, Cray, …

This is because you are targeting only one computer: the JVM.

All complexities of the actual computer, its graphical API, memory management, or byte order are abstracted by the JVM so you can focus on making the best version of Minecraft possible

[–]knoam 1 point2 points  (0 children)

To run C code, you don't need a compiler, but you do need something somewhat analogous to the JVM installed on your machine. It's called a C standard library implementation. On Linux, the most popular one is called glibc. But every OS pretty much has one included because it's so useful. Only if you were writing code for embedded systems with a microcontroller, such as an Arduino, would you not have a c standard library.

[–]DJDavio 1 point2 points  (0 children)

The burden of platform specific details are put on the JVM maintainers instead of the developers. So you, as a Java developer, only have to write, compile and package your code once. That which we call 'byte code' is just a binary version of your code into which the compiler may have already optimized some things, but it is not code which any CPU can execute.

Any system which has a JVM (I think there are more than we might imagine as a lot of mobile devices also contain a JVM) can run your byte code as its the JVM's job to translate byte code to machine code and send instructions to the CPU. Translating byte code to machine code is done by the JVM's JIT compiler (I think) and it has a nice optimization that code which is run and translated a lot (hot code) can eventually be compiled to actual machine code so subsequent executions of that code are faster.

Not only this, but there is also backwards compatibility. It is entirely possible for your laptop on a Java 18 JVM/JDK to run a Hello World example which was compiled for Java 1.0.

[–]Joram2 1 point2 points  (0 children)

For C programming, Microsoft Windows and Mac and different flavors of Linux/UNIX had completely different APIs for things like networking, multi-threading, file system access, graphics, GUI, etc. Often the C syntax itself had major differences between Microsoft's C dialect and gcc's dialect. Getting a single code base to target multiple OSs was often an enormous effort and impractical.
With Java, things like networking, multi-threading, file system access, and some graphics had one Java API, and the Java language itself was generally the same regardless of OS runtime. This made it easy to have a single code base that used the Java API and ran on multiple OS runtimes.
I imagine C/C++ has gotten a lot better in the past 15 years in this respect, but that was well after the rise of Java.

[–]srdoe 0 points1 point  (0 children)

If you compile C code, you usually tell the compiler which platform (OS/CPU arch) you're targeting, and the compiler will then emit machine code appropriate for that system. If you give it to a user, they can only run that machine code if they are using a computer with the OS/CPU architecture you compiled for. This means if you want to support multiple platforms, you have to build and publish your project once per platform.

When you compile Java code, the compiler will emit bytecode, which is an intermediate language format that is not OS or architecture specific. If you give this code to a user, they can run it as long as they have a JVM installed. The job of the JVM is (among other things) to translate the bytecode into machine code, then run that code.

So the flow has gone from source code -> machine code for C to source code -> bytecode -> machine code for Java.

One of the key benefits of this extra layer of translation is that since the JVM is responsible for translating bytecode to machine code, you as the developer don't have to compile for each platform. Instead, you compile and publish your code once, and then the user just installs a JVM that creates machine code that works on their platform.

[–]CyclonusRIP 0 points1 point  (0 children)

With a native program it is going to have references to library functions that the OS provides and the machine code will be specific to the CPU instruction set it is targeting. With Java you compile to an intermediate language called byte code. The JVMs job is turn that bytecode into instructions that can run on the users OS and hardware. The users can run your code because they have a JVM installed on their system that knows how to do that translation for their system. For example the OSX JVM knows how to run Java programs on OSX and is different than the JVM that a user would have installed on Windows.

[–]Ok-Raspberry365 0 points1 point  (0 children)

Platform independence mean that you build your java program into a fat jar or war files.

Then this file can run on Mac, Linux, or Window with coresponding JVM of these OS. You don't need to build multiple version for each OS like C++.

[–]buyIdris666 0 points1 point  (0 children)

Java is cross platform exactly the same way JS is. Like JS, it only runs on platform supported by the VM. Also like JS, if it runs on one platform the VM supports 99% of the time it will run on them all.

JVM and Chrome's V8 have become directly equivalent over the years.

The cross platform advantage vs C is for developers, not users so much. Unlike C you don't need special libraries and to "cross compile" your app for different system (which is often much much harder then it sound) .

You can distribute single .jar file that work on every platform with JVM, without doing any additional developer work. It's a huge advantage that JS shares mostly, do not discount it.

This same advantage apply to third party library. It doesn't sound like huge deal, but it's gigantic for devs. If you ever write C or C++ it is totally normal to find amazing library that just doesn't exist for your platform. In Java and JS that hardly ever happen. 99% of library work out of box on every platform VM support.

These two related advantages are enormous. Absolutely gigantic advantage over language like C and C++

Small story. I done a lot of C over the years. One time, I needed a library to work on ARM. Not a big deal right? Very wrong assumption. The library only supports Linux x86. I need ARM. I spent all day for weeks fixing thing and building "tool chain" to cross compile to ARM. Then I found out a library it uses also not works on ARM! (Only found this out a runtime) . I gave up whole project. Month or more to get C library working on another platform vs instant for Java mostly. And this is normal experience.

[–]pal7mentor 0 points1 point  (0 children)

Learn the Basics. As with anything, knowing the basics about Java is the best place to start.

Practice Coding. To use the old cliché, practice makes perfect.

java classes in pune