Java has been around a long time now and machines were a lot slower in the JDK 1.0 days so they were probably considering the poor performance of requiring a minimum Object overhead.
And the distinction has worked elsewhere. Objective-C for instance has an NSObject in Cocoa but the language is a proper superset of C and has no problem with plain types. (Granted if you use low-level objcruntime functions, it will be more complex to pass in C data types that are not objects but they still work.)
Despite not requiring Object everywhere, early Java had a frustrating tendency to use Object for many basic things, seemingly requiring boxing and casting more than it should. (At least with Objective-C++ you had the option of some std:: container of plain data, if you didn’t want to wrap in some NS<container> type.) Both Java and Objective-C ultimately changed the syntax to allow type specifications in containers to compensate.
> Java has been around a long time now and machines were a lot slower in the JDK 1.0 days so they were probably considering the poor performance of requiring a minimum Object overhead.
Never mind the machines back when Java was 1.0 — one of the reasons Project Valhalla exists is that "the poor performance of requiring a minimum object overhead" is very much still a significant cost!
The biggest reason is the pressure on HFT scenarios that want to migrate to Java and see it as a blocker, and the new kids on the block that offer better support for such scenarios.
Almost correct, except that Sun ignored the prior work with languages like Eiffel, Sather, Modula-3, Oberon variants.
In Eiffel for example, you can declare what is the default behavior (reference or value type), and then any user of the type is able to still override it at declaration site.
Maybe, but the fact that they feel the market pressure to add them to stay competitive on modern hardware vs what .NET did a few years later, means it wasn't properly right as well.
Java was released in Jan 1996, .NET in Feb 2002. A lot changed in those six years. .NET built on the shoulders of the giant that was Java, as well as the lessons from the globally accelerating development enabled by the internet.
Those early decisions may not have been technically right in some sense, but technical considerations are not the only factor.
Mesa/Cedar was developed at Xerox PARC in 1981 and is cited as one of Java's influences.
One of its descendants, Modula-3 designed around 1986, is equally cited as yet another Java reference.
Both of them, had value types and compiled ahead of time into native code. Although Mesa/Cedar was native in the Lisp Machine sense, given the Xerox PARC microcoded CPU architectures.
There are some old posts from Gosling where he discusses about Eiffel/Sather features.
So the knowledge was there, it was just a bit disappointing not getting them, because as you say technical considerations were not the only factor.
Note that the first version of Java was delivered under tremendous time pressure. I guess they would have done a few things differently if the Sun engineers had more time.
And the distinction has worked elsewhere. Objective-C for instance has an NSObject in Cocoa but the language is a proper superset of C and has no problem with plain types. (Granted if you use low-level objcruntime functions, it will be more complex to pass in C data types that are not objects but they still work.)
Despite not requiring Object everywhere, early Java had a frustrating tendency to use Object for many basic things, seemingly requiring boxing and casting more than it should. (At least with Objective-C++ you had the option of some std:: container of plain data, if you didn’t want to wrap in some NS<container> type.) Both Java and Objective-C ultimately changed the syntax to allow type specifications in containers to compensate.