Hacker News new | past | comments | ask | show | jobs | submit login

I find a lot of similarities between Java and C++. Java is basically a subset of C++ with some sugar around. When I was learning Java, I just made a link between Java constructs and C++ constructs and that allowed me to learn Java in one day and start getting things done. Of course I took few years more to master Java, but that's another matter.

So Java "reference" is C++ pointer without asterisks and ->. All java methods are virtual. Java interface is full-abstract class without fields (in Java 8 even not so full-abstract). Multiple inheritance only with interfaces. No generics (I learned Java 1.4), one common ancestor Object, friendly GC releasing you from the pain of memory management.

Basically the only new concept is package. Otherwise it's stripped C++ with different runtime library.




> Java is basically a subset of C++ with some sugar around.

Not sure where you got that from... the notion of a class being a "reference type", which is the foundation of Java, doesn't even exist in C++. Every class type is a value type in C++.


Sure, it does. In C++, you can declare everything on the heap, then pass pointers by value. In Java, you declare everything on the heap (because you can't declare it anywhere else), then pass pointers by value (because you can't pass classes in any other way).

The only difference is that Java's subset also does not include pointer arithmetic, so this is actually a safe coding practice, because it allows for garbage collection to be performed.


You're not countering the same claim I'm making.

Yes, C++ can emulate what Java is doing, but no, that's not what I'm saying. I'm saying C++ classes are not reference types, i.e., every class you define is always a value type, which is the exact opposite of Java. Obviously C++ also has pointers/references that could help you emulate Java, but that's beside the point. The point is that classes work differently in C++ and Java, and neither functionality is a subset of the other.


I suppose I'm not seeing the difference between Java's restriction of only using reference semantics, and C++'s option of using reference semantics. Since Java only provides reference semantics, while C++ allows both reference semantics and value semantics, this would make Java be a subset of C++, in this regard.


You can always declare something like:

  class MyClass_ { ... }
  typedef MyClass_ *MyClass;
and you have identical "reference" semantics in C++. Of course you have to use `->` instead of `.`, but does it matter?


That was entirely intentional. Java adopted some C/C++ conventions that its designers knew were suboptimal, like == being reference, i.e. pointer, equality, switch statement with fallthrough etc. (even automatic number promotion, though I'm not sure it was clear to Java's designers that may not be such a good idea) precisely because they wanted C/C++ developers -- basically the entire market for Java developers at the time -- to be able to learn it quickly and make it feel familiar. Familiarity was purposefully chosen as one of the top design goals, as explained by James Gosling[1].

Today, these decisions would have been different, as C++ no longer reigns supreme. I find that Kotlin has completely adopted all of Java's core values, but modernized the specific syntax and semantics. Kotlin is what Java would have been if it had been designed today. The fact that Kotlin has made interoperation so seamless (you can switch any single Java class with a Kotlin file in an existing project -- IntelliJ would even automatically translate it for you) makes transitioning from Java to Kotlin (if you want) so smooth and gradual that it's a tru pleasure (even working on a mixed codebase).

[1]: http://www.win.tue.nl/~evink/education/avp/pdf/feel-of-java....


FYI: C conventions are also used in Objective-C.

OTOH - where are the named parameters in Java method calls?

The creators had Objective C in mind, but the result is so stripped down, it becomes an ink blot test for the viewer to see what they want :-)

I sure as hell don't see "Eiffel", though. JavaBeans are evil.


Though, I think people are mixing together two different discussions in the article and thread: the internal design of the language, and the external consumption of the language. As a user of either language, where the internals can be considered as a black box, sure, they're both incredibly similar.


> I find a lot of similarities between Java and C++. Java is basically a subset of C++ with some sugar around.

I learned Java and C++ at the same time. And I had a hard time doing it because I believed Sun's marketing department that Java was a better C++. When I finally realized that was a classic bit of puffery, and that the marketing was simply trying to make Java look powerful by association with C++, I was able to make some progress.


I believe the similarities you find between Java and C++ are entirely intentional. But I respectfully disagree with:

> Java is basically a subset of C++ with some sugar around.

Here are a few reasons why:

* As you said, all Java classes inherit from a common type; java.lang.Object (Smalltalk).

* Inner classes automatically have a reference to the containing class (not in C++, though Java "nested classes"[1] behave similar to C++ structs/classes).

* java.lang.ClassLoader has no corresponding abstraction in C++.

* C++ has pass-by-reference semantics which is completely missing in Java.

* C++ supports destructors intrinsically.

* All definitions must exist within a type in Java. There is no concept of a "free standing" definition.

* Java provides meta-objects by way of java.lang.Class for all classes (not present in C++).

* Java does not support stack-based allocation except for built-in POD's.

> Java interface is full-abstract class without fields (in Java 8 even not so full-abstract). Multiple inheritance only with interfaces.

A Java interface has a distinct type within the type system, yes, and there exist meta-objects describing them generated as well. But until Java 8, interfaces had no behaviour and could only declare static fields.

> So Java "reference" is C++ pointer without asterisks and ->.

Pretty much.

As an aside, it has always cracked me up that a language touted as having no pointers has a "NullPointerException" class. (I am easily amused)

1 - http://docs.oracle.com/javase/tutorial/java/javaOO/nested.ht...


> * As you said, all Java classes inherit from a common type; java.lang.Object (Smalltalk).

You can limit yourself in C++ to inherit your objects from a common type. I believe that Qt did just that, for example. So this is a subset of C++.

> * Inner classes automatically have a reference to the containing class (not in C++, though Java "nested classes"[1] behave similar to C++ structs/classes).

That's a good example of simple sugar. Inner class just have pointer to the outer class and constructor with this parameter. Java compiler emits this code automatically. Yes, there's no such thing in C++, but it's very simple to emulate.

> * C++ has pass-by-reference semantics which is completely missing in Java. > * C++ supports destructors intrinsically. > * All definitions must exist within a type in Java. There is no concept of a "free standing" definition. > * Java does not support stack-based allocation except for built-in POD's.

Yes, Java is subset of C++ in that regard. C++ has more features which were stripped out.

> * java.lang.ClassLoader has no corresponding abstraction in C++. > * Java provides meta-objects by way of java.lang.Class for all classes (not present in C++).

Actually those systems could be emulated more or less in C++. Windows does have COM (and there are a lot of less known, but similar systems) which allows to dynamically load classes with virtual methods, etc. Qt implements (with some preprocessor magic) reflection for C++. But generally yes, C++ does not have any kind of runtime reflection (except dynamic_cast) and dynamic code loading, I agree here. What I want to point out is, that those features are provided by JVM. Java as a language does not have anything related to reflection or class loading. So probably it's not fair to compare Java + JVM to C++.

> As an aside, it has always cracked me up that a language touted as having no pointers has a "NullPointerException" class. (I am easily amused)

That's very unfortunate mess of terms. Pointers should be pointers, even if there's no pointer arithmetic in the language. Now we have pointers, references, pass-by-reference and beginners having hard time to understand what that even mean.


Your itemized explanations of what can be done in C++ only reinforces that the environments are quite different.

One of the wonderful things about C++[1] is that it can express just about anything which can be encoded in a program. GC, common base types, functional programming, imperative programming, object oriented programming, meta-programming, logic-based systems, dynamic module systems (a la Apache modules[2]), and a bunch more.

But that does not make a language such as Java a subset, unless your premise is that any language which can in some way be expressed in or embedded int C++ qualifies as a subset. If that's the case, then pretty much every language "is a subset of C++" (and yes, even Lisp[3]).

1 - Yes, I mean "wonderful things" as I have worked in C++ for many years. Still do when the problem calls for it.

2 - http://shop.oreilly.com/product/9781565925670.do

2 - https://common-lisp.net/project/ecl/


I knew Delphi and some basic C++ when I learnt Java, and I found it much more similar to Delphi.


Ditto. Strong types, bounds checking, and after Java 1.1, recursive nesting of program components.

More than Microsoft, I think Java killed Borland. Java had no IDE back in 95/96, but the compiler was free and it also ran on Linux, which Borland was late to adopt.

... then Anders went to work for Microsoft, and the rest is tragedy.


I keep seeing that "strong types" comment here. In what sense are Java types "strong" and C++ types "weak"?


For one example:

    float a = 1.0; // compilation error in java, no problem in C++
For another:

    int a[5] = { 0, -1, 2, 3, 4 };
    (1+a) = 1; // :)
Also:

    assert( !(1/2) );
Also:

    enum Foo {A, B};
    enum Bar {C, D};
    
    Foo e1 = A;
    Bar e2 = C;
    int i = 0;

    assert(e1 == e2); // warning
    assert(e1 == i); //no problem whatsoever


I'd argue that in the case of your first example, C++ is correct. Promoting int to double in this case does not bother me whatsoever. (In fact, mathematically, an integer is a real, though the reverse is not always true.

I will concede that the others are problematic...


In 1 the problem is silently discarding double precision to float precision. I edited the example to be less confusing.


Ah. Yes, I was confused; I thought the issue was the promotion of the 2 from int to floating point.


Also I made an error - should have been

    *(1+a) = 1;
Still bad but not as bad.


After thinking about it a bit, that also is well-typed in C. (You can argue that it shouldn't be allowed, but that's a different argument than that the language is not strongly-typed because of that feature.)


Or:

  1[a] = 1;


Exactly my experience - coming from C++, I never had to "learn" Java at all, and (at least until recently) there were only a handful of Java idioms that were unique to it that you had to grok. And this is exactly what you'd expect from a sensible pragmatic language design back then - take the dominant language in a domain (C++) and simplify it.


I think the stronger similarities came much later when generics were introduced. Both languages were then on a path of horrific type-nazism at that point. Strong static typing + a weak type system = rubbish. Sprinkle in design pattern-itis you have the mess both languages are currently in.

Before then java wasn't so bad.


Before then Java was dynamicly typed language pretending it's staticly typed :)

    List doSth(Object a, Object b) { ... }


It's questionable what's better: simple type system without generics (Java 1.4, Go), something in between (Java 1.5) or something full-featured but hard to learn (Scala).

Scala pretends to solve this problem by "layering" code. Complex types are for libraries and users should use libraries. But IMO it never worked. Problems arising, "users" have to debug into library code and they have to deal with full-featured types anyway.

My only real wish in regard to Java 1.4 was that I would be able to implicitly cast Object to anything (like I can in Objective C). That would help to reduce type clutter a lot.


> Scala pretends to solve this problem by "layering" code.

From my perspective that's the large difference between Java and Scala. In Java, complexity leaks into the use-site (especially with Generics), in Scala it's possible to shield the user from that complexity.


Yes, I would agree with this. I was able to learn (not master) Java very quickly for Android development as I was familiar with C++, so it looks to me like a simplified C++ (isn't every language???) with some restrictions placed on it (inheritance etc.).


I think it helps that Java (like C#) is a very safe language to use, there aren't many dark holes for you to fall into like there are for C++.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: