I had experience on Java, because of some results, I need to code in C, is it difficult to switch from Java to C? And what is the biggest different between these two languages?
Without question, first and foremost, it's the manual memory management.
Second is that C has no objects so C code will tend to be structured very differently to Java code.
Edit: a little anecdote: back 15 or so years ago when it was common to log on to your local ISP on a UNIX command prompt when PPP was still pretty new and when university campuses still had an abundance of dumb terminals to UNIX servers, many had a program called fortune that would run when we logged on and output a random geeky platitude. I literally laughed out loud one day when I logged in an read:
C -- a programming language that
combines the power of assembly
language with the flexibility of
assembly language.
It's funny because it's true: C is the assembly language of modern computing. That's not a criticism, merely an observation.
Perhaps the most difficult concept is learning how to handle pointers and memory management yourself. Java substantially abstracts many concepts related to pointers, but in C, you'll have to understand how pointers are related to one another, and to the other concepts in the language.
Besides pointers and memory management, C is not an object-oriented language. You can organize your code to meet some object based concepts, but you will miss some features like inheritance, interfaces and polimorphism.
Java has a massive standard library, while C's is tiny. You'll find yourself re-inventing every kind of wheel over and over again. Even if you're writing the fifteenth linked list library of your career, you might very well make the same mistakes you've made before.
C has no standard containers besides arrays, few algorithms, no standard access to networking, graphics, web anything, xml anything, and so on. You have to really know what you're doing not to accidentally invoke undefined behaviour, cause memory corruption, resource leaks, crashes, etc. It's not for tourists.
Good luck.
Apart from Standard C being a non-OO language, the standard library being very small (and in some places, just plain bad), the goriness of manual memory handling, the complete lack of threading utilities (or even awareness of multithreading), the lax "type system" and being built for single-byte character sets, I think the greatest conceptual difference is that you have to have a clear notion of ownership of objects (or memory chunks, as it becomes in C).
It's always good practice to specify ownership of objects, but for non-GCed languages it is paramount. When you pass a pointer to another function, will that function assume ownership of the pointer or will it just "borrow" it from you for the duration of the call? When you write a function taking a pointer argument, does it make sense for you to assume ownership of the pointer, or does the pointee continue living after the function terminates?
People have covered the big differences: memory management, pointers, no fancy objects (just plain structs). So I will list a couple of minor things:
You have to declare things at the beginning of a block of code, not just when you want to use them for the first time
Automatic type conversion between pointers, booleans, ints and just about anything. This is typical C code: if (!ptr) { /* null pointer detected */ }
No bounds-checking in any sense, and fancy pointer arithmetic allowed. It is explicitly legal to reference things outside their bounds: ptr2 = ptr + 10; ptr2[-10] ++; is equivalent to ptr[0] ++;.
Strings are zero-terminated char arrays. Forgetting this and the previous point causes all sorts of bugs and security holes.
Headers should be separated from implementation code (.h and .c), and must explicitly reference each other via #include statements, avoiding any circular dependencies. There is a preprocessor, and compile-time macros (such as #includes) are a vital part of the language.
And finally -- C has a goto statement. But, if you ever use it, Dijkstra will rise from the grave and haunt you.
Java is a garbage collected environment, C is not. C has pointers, Java does not. Java methods use pass by reference more often, implicitly, whereas C you must explicitly indicate when you are passing by reference. Lot more considerations to be sure.
Related
I had a job interview for probation(? I'm not sure if that's the word)
and interviewer asked me to tell him what are the differences between structure and class.
So I told him everything I knew and everything that I've read on msdn.
And the guy said "not enough", I didn't have a clue.
So he said:
The struct are optimized, so if there is and integer and float, which have some bites identical, then it will save this space, so struct with
int=0 and float=0 is half the size of int=int.MAX, float=float.MIN.
Okay. So I was like - didn't hear about that.
But then, after the interview I was thinking about it and it doesn't really make sense to me. It would mean, that the struct size differs while we're changing the value of some variable in it. And it can't really be in the same place in memory, what if there is a collision while expanding. And we would have to write somewhere what bits we're skiping, not sure if it would give any optimization.
Also, he asked me at the begging what is the difference in struct and class in Java. To which I have answered, that there is no struct in Java and he said "Not for programmers, but Numeric types are structures" I was kind of like WTF.
Basically the question is:
Did this guy know something, which is very hard to get to know (I mean, I was looking for it on the web, can't find a thing)
or maybe he doesn't know anything about his job and tries to look cool at the job interviews.
The guy seems to be confused about the StructLayoutAttribute that can be applied to C# structs. It allows you to specify how the struct's memory is laid out, and you can, in fact, create a struct that has fields of varying types that all start at the same memory address. The part he seems to have missed is that you're going to only use one of those fields at a time. MSDN has more info here. Look at the example struct TestUnion toward the bottom of the page. It contains four fields, all with FieldOffset(0). If you run it, you can set an integer value to the i field and then check the d field and see that it has chnaged.
To me it looks like (one of you) was not talking about C# structs/classes but rather about more low-level or more general structs.
There is this special sort of memory optimization used e.g. in
1. C (unions)
and in
2. Pascal (variant records)
see e.g. article How do I translate a C union into Delphi? for an example.
Special form of this "structure" with dynamic polymorphic memory allocation is known as
3. http://en.wikipedia.org/wiki/Variant_type
and it was used heavily for inter-process data exchange in OLE automation APIs, in the pre-C# era (for decades in multitude of languages).
4. (s)he might be also talking about structure serialization format vs class in-memory format (see e.g. https://developers.google.com/protocol-buffers/docs/encoding for example of C# structure serialization)
5. you might be also talking about differences of internal JVM memory allocation (see e.g. http://blog.jamesdbloom.com/JVMInternals.html) which reminds me that you might be talking about the class file format and encoding of structs and special numeric literals vs encoding of classes (http://blog.jamesdbloom.com/JVMInternals.html#constant_pool)
So after 5 guesses I believe there is something lost in your translation of your talk with the interviewer and (s)he probably browsed into an area you claimed you know and it turned out you don't. It also might be that (s)he started talking bullshit and checked your reactions. Lying about your skills on the resume is not recommended in any job (e.g. http://www.softwaretestinghelp.com/5-common-interview-mistakes/). I'd vote for the interviewer knew the inteviewing job well enough
I just started learning Scala, and I'm having the time of my life. Today I also just heard about Scala for Android, and I'm totally hooked.
However, considering that Scala is kind of like a superset of Java in that it is Java++ (I mean Java with more stuff included) I am wondering exactly how the Scala code would work in Android?
Also, would the performance of an Android application be impacted if written with Scala? That is, if there's any extra work needed to interpret Scala code.
To explain a little bit #Aneesh answer -- Yes, there is no extra work to interpret Scala bytecode, because it is exactly the same bits and pieces as Java bytecode.
Note that there is also a Java bytecode => Dalvik bytecode step when you run code in Android.
But using the same bricks one can build a bikeshed and the other guy can build a townhall. For example, due to the fact that language encourages immutability Scala generates a lot of short living objects. For mature JVMs like HotSpot it is not a big deal for about a decade. But for Dalvik it is a problem (prior to recent versions object pooling and tight reuse of already created objects was one of the most common performance tips even for Java).
Next, writing val isn't the same as writing final Foo bar = .... Internally, this code is represented as a field + getter (unless you prefix val with private [this] which will be translated to the usual final field). var is translated into field + getter + setter. Why is it important?
Old versions of Android (prior to 2.2) had no JIT at all, so this turns out to about 3x-7x penalty compared to the direct field access. And finally, while Google instructs you to avoid inner classes and prefer packages instead, Scala will create a lot of inner classes even if you don't write so. Consider this code:
object Foo extends App {
List(1,2,3,4)
.map(x => x * 2)
.filter(x => x % 3 == 0)
.foreach(print)
}
How many inner classes will be created? You could say none, but if you run scalac you will see:
Foo$$anonfun$1.class // Map
Foo$$anonfun$2.class // Filter
Foo$$anonfun$3.class // Foreach
Foo$.class // Companion object class, because you've used `object`
Foo$delayedInit$body.class // Delayed init functionality that is used by App trait
Foo.class // Actual class
So there will be some penalty, especially if you write idiomatic Scala code with a lot of immutability and syntax sugar. The thing is that it highly depends on your deployment (do you target newer devices?) and actual code patterns (you always can go back to Java or at least write less idiomatic code in performance critical spots) and some of the problems mentioned there will be addressed by language itself (the last one) in the next versions.
Original picture source was Wikipedia.
See also Stack Overflow question Is using Scala on Android worth it? Is there a lot of overhead? Problems? for possible problems that you may encounter during development.
I've found this paper showing some benchmarks beetween the two languages:
http://cse.aalto.fi/en/midcom-serveattachmentguid-1e3619151995344619111e3935b577b50548b758b75/denti_ngmast.pdf
I've not read the entire article but in the end seems they will give a point to Java:
In conclusion, we feel that Scala will not play a major role in the
mobile application development in the future, due to the importance of
keeping a low energy consumption on the device. The strong point of
the Scala language is the way its components scale, which is not of
major importance in mobile devices where applications tend to not
scale at all and stay small.
Credits to Mattia Denti and Jukka K. Nurminen from Aalto University.
While Scala "will just work", because it is compiled to byte code just like Java, there are performance issues to consider. Idiomatic Scala code tends to create a lot more temporary objects, and the Dalvik VM doesn't take too kindly to these.
Here are some things you should be careful with when using Scala on Android:
Vectors, as they can be wasteful (always take up arrays of 32 items, even if you hold just one item)
Method chaining on collections - you should use .view wherever possible, to avoid creating redundant collections.
Boxing - Scala will box your primitives in various cases, like using Generics, using Option[Int], and in some anonymous functions.
for loops can waste memory, consider replacing them with while loops in sensitive sections
Implicit conversions - calls like str.indexWhere(...)will allocate a wrapper object on the string. Can be wasteful.
Scala's Map will allocate an Option[V] every time you access a key. I've had to replace it with Java's HashMap on occasion.
Of course, you should only optimize the places that are bottlenecks after using a profiler.
You can read more about the suggestions above in this blog post:
http://blogs.microsoft.co.il/dorony/2014/10/07/scala-performance-tips-on-android/
Scala compiler will create JVM byte code. So basically at the lower level, it's just like running Java. So the performance will be equivalent to Java.
However, how the Scala compiler creates the byte code may have some impact on performance. I'd say since Scala is new and due to possible inefficiency in its byte code generation, Scala would be a bit slower than Java on Android, though not by a lot.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Java operator overload
In c++, we can perform the operator overloading. But Java is also a Object oriented language. So why java doesn't support overloading?
http://java.sun.com/docs/white/langenv/Simple.doc2.html
There are no means provided by which
programmers can overload the standard
arithmetic operators. Once again, the
effects of operator overloading can be
just as easily achieved by declaring a
class, appropriate instance variables,
and appropriate methods to manipulate
those variables. Eliminating operator
overloading leads to great
simplification of code.
The last statement is of course very subjective.
Actually, it does support operator overloading... of a very limited, built-in only nature. For instance "+" is overloaded for String's in addition to the usual arithmetic.
Of course, most people want to know why Java does not support user-defined operator overloading. :-) The simplest answer seems to be that the Java creators did not, at the time, see any clean way to add it to the language without making Java a mess (like C++) in the process.
it's design goals to make java simpler than c++
We wanted to build a system that could
be programmed easily without a lot of
esoteric training and which leveraged
today’s standard practice. So even
though we found that C++ was
unsuitable, we designed Java as
closely to C++ as possible in order to
make the system more comprehensible.
Java omits many rarely used, poorly
understood, confusing features of C++
that, in our experience, bring more
grief than benefit.
from here:
The Java Language: An Overview
The code is harder to understand when you use operator overloading in c++. May be that was the reason why Java developers decided not to implement it.
Really the code rich with overloaded operators can be very misleading and hard to read, just like the code with a plenty of macros.
Note that there's an anomaly in that the 'plus' operator is overloaded for java.lang.String.
Way back when, the news was that the Java team looked at other languages (primarily C++) and tried to make a judgment call as to what language level features to include (or exclude) from Java.
Operator overloading was a big new feature in C++ and lots of budding programmers used it to solve problems in interesting ways. Unfortunately, most of those ways were buggy, and few programmers overloaded operators in ways that were "programmer portable". As a result, reading a program would often miss that "magic" code had been introduced in the "+" operator (or something else). Outside of numbers (vectors, etc.) you also had disagreements as to what "+" might mean.
So the cover story (no idea if it was true) was that the Java team saw that you could just name methods sum.plus(...) and it would be obvious that the call was to user written code (which could be overloaded) while the reserved operations "+", etc. would only did what the language defined. This would increase some types of code readability at the expense of a few extra words.
Is it true, or is it an attempt to back fill history with rationalizations? I don't know. Perhaps the language implementers just were busy trying to get Java working and didn't get around to operator overloading by release date. Either way, it greatly increases the readability of Java in 95% of all cases, at the expense of making vector math a bit wordy.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Can anyone help comparing and contrasting between Java and cobol in terms of technical differences as well as architectural design styles
Similarities
Cobol and Java were going to change the world and solve the problem of programming.
Neither lived up to the initial hype.
There are now very large, bloated Cobol and Java programs that are used by banks and are "legacy" ... too large and critical to rewrite or throw away.
Cobol introduce the idea of having long, readable names in their code. Java recommends long, readable names.
Differences
Cobol was invented by an American, Grace Murray Hopper, who received the highest award by the Department of Defense, the Defense Distinguished Service Medal.
Java was invented by a Canadian, James Gosling, who received Canada's highest civilian honor, an Officer of the Order of Canada.
3 COBOL convention uses a "-" to separate words in names, Java convention uses upper/lower CamelCase.
COBOL was popular for the simple reason, to develop business applications.
Since the syntax was so clear and human-like, written in procedural style, it was for that reason, that made adapting to the changes in the business environment much easier, for example, to assign a value of pi to a variable, and then subtract zero from it - simple example to show the actual COBOL statements/sentences (it is years since I last programmed in Cobol)
MOVE 3.14 INTO VARPI.
SUBTRACT ZERO FROM VARPI GIVING VARPIRESULT.
IF VARPIRESULT AND ZERO EQUALS VARPI THEN DISPLAY 'Ok'.
If I remember, the COBOL sentences have to be at column 30...
And it is that, hence easier to troubleshoot because any potential business logic error can be easily pin-pointed as a result. Not alone that, since COBOL ran on mainframe systems, it was for a reason, the data transfer from files were shifted at a speed that is light-years ahead of the other systems such as PC's and that is another reason why data processing in COBOL was blindingly fast.
I have worked on the Y2k stuff on the mainframe (IBM MVS/360) and it was incredible at the dawn of the 21st century, praying that the fixes I put in wouldn't bring the business applications to their knees...that was hype, aside from that..to this day, it is still used because of the serious transfer speed of data shuffling around within mainframes and ease of maintainability.
I know for starters, Java would not just be able to do that, has Java got a port available for these mainframes (IBM MVS/360, 390, AS400)?
Now, businesses cannot afford to dump COBOL as they would effectively be 'committing suicide' as that is where their business applications resides on, which is the reason why the upgrade, migration, porting to a different language is too expensive and would cause a serious headache in the world of businesses today...
Not alone that, imagine having to rewrite procedural code which are legacy code and could contain vital business logic, to take advantage of the OOP style of Java, the end result would be 'lost in translation' and requiring a lot of patience, stress and pressure.
Imagine, a healthcare system (I have worked for one, which ran on the system I mentioned above), was to ditch all their claims processing,billing etc (written in COBOL) to Java, along with the potential for glitches and not to mention, serious $$$ amount of money to invest which would cost the healthcare company itself far more, the end result would be chaos and loss of money, and customers (corporations that offer employee benefits) would end up dumping the company for a better one.
So to answer your question, I hope I have illustrated the differences - to summarize:
COBOL is:
Procedural language
Simple human like syntax
very fast on mainframe systems
Easy to maintain code due to syntax
In contrast,
Java is:
Object Oriented
Syntax can get complicated
Requires a Java Virtual Machine to run and execute the compiled bytecode.
Hope this helps,
It is easier to point out what they have in common instead of listing their differences.
So here is the list:
You can use both to make the computer do things
They both get compiled to yet a different language (machine code, byte-code)
That is it!
Similarities:
Both extremely verbose and created with pointy-haired bosses, not programmers, in mind.
Both used primarily for boring business software.
Both have huge legacy and are going to be around a while.
Both languages target the "Write Once, Run Anywhere" idea. If vendor specific extensions are avoided, Cobol is very portable.
Cobol is very much a procedural language, while Java is very much an object oriented language. That said, there have been vendor specific OO extensions to Cobol for decades, and the new specification contains a formal specification. It is also possible to write procedural code in Java, you can easily make a program out of a single main() method.
Both are widely used in enterprise computing for their relative ease of use. Both languages are somewhat hard to shoot yourself in the foot with, compared with other common languages like C and C++.
The most significant difference is that Cobol supports native fixed point arithmetic. This is very important when dealing with financals. Most languages, Java included, only support this via add on libraries, thus they are many orders of magnitude slower when dealing with fixed point data and prone to (potentially very expensive) errors in that library code.
Cobol is a pure procedural language, not even functions in it (I used cobol in the 90s, so it might have changed since).
Java is OO (Although I heared there is a OO version for Cobol too), Oh...And the syntax is different.
Excelent list of similarities and differences : http://www.jsrsys.com/jsrsys/s8383sra.htm
It'swhat we do!
COBOL: COBOL Concept Description
Java: Java/OO Similar Concept
++: What Java/OO adds to Concept
When I began Java, I used to think the OO (Object Orientation) was "just like" good programming practices, except it was more formal, and the compiler enforced certain restrictions.
I no longer think that way. However, when you are beginning I think certain "is similar to" examples will help you grasp the concepts.
COBOL: Load Module/Program
Java: Class
COBOL: PERFORM
Java: method
++: can pass parameters to method, more like FUNCTION
other programs/classes can call methods in different classes if declared public. public/private gives designer much control over what other classes can see inside a class.
COBOL: Working Storage, statically linked sub-routine
Java: instance variables
++: (see next)
COBOL: Working Storge, dynamically loaded sub-routine
Java: Class variables
++: Java can mix both Class variables (called static, just the reverse of our COBOL example, and instance variables (the default).
Class variables (static) occur only once per Class (really in one JVM run-time environment).
Instance variables are unique to each instance of a class.
Here is an example from class JsrSysout. From my COBOL background I like to debug my code by DISPLAYing significant data to the SYSOUT data set. There is a Java method for this, System.out.prinln(...). The problem with this method is that the data you want just scrolls off the Java console, the equivalent of SYSOUT or perhaps DISPLAY UPON CONSOLE if you had your own stand-alone machine. I needed a way to easily do displays that would stop when the screen was full. Since there is only one Java console, the line-count for the screen clearly needs to be a class variable, so all instances (each program/class that logs here has its own instance of JsrSysout) stop at the bottom of the screen.
Multiple Instances of same class:
One (calling program) class can create multiple instances of the same class. Why would you want to do this? One good COBOL example is I/O routines. In COBOL you would need to code one I/O routine for each file you wish to access. If you want to open a particular file twice in one run-time environment you would need a different I/O routine with a different name, even if the logic was identical.
With Java you could code just one class for a particular logical file type. Then for each file you wish to read (or write) you simply create another instance of that class using the new operator. Here are some snippets of code from program IbfExtract that do exactly that. This program exploits the fact that I have written a class for Line Input, and another class for Line Output. These are called JsrLineIn and JsrLineOut.
This illustrates another dynamic feature of Java. When output is first created, it is an array of null pointers, it takes very little space. Only when a new object is created, and the pointer to it implicitly put in the array does storage for the object get allocated. That object can be anything from a String to an very complex Class.
COBOL: PICTURE
Java: No real equivalent.
I therefore invented a method to mymic a ZZZ,ZZZ,... mask for integer input. I have generally grouped my utility functions in JsrUtil. These are methods that really don't related to any type of object. Here is an example of padLeft that implements this logic. padLeft is also a good example of polymorphism. In COBOL, if you have different parameter lists you need different entry points. In Java, the types of parameters are part of the definition. For example:
COBOL: Decimal arithmetic
Java: Not in native Java, but IBM has implemented some BigDecimal classes.
I consider this the major weakness of Java for accounting type applications. I would have liked to see the packed decimal data type as part of the native JVM byte architecture. I guess it is not there because it is not in C or C++. I have only read about the BigDecimal classes, so I can't realy comment on their effectiveness.
COBOL: COPY or INCLUDE
Java: Inheritance
++: Much more powerfull!
In COBOL, if you change a COPY or INCLUDE member, you must recompile all the programs that use it. In Java, if program B inherits from program A, a change in program A is automatically inherited by program B without recompiling! Yes, this really works, and lends great power to Java applications. I exploited this for my Read/Sort/Report system. Class IbfReport contains all the basic logic common to the report programs. It has appropriate defaults for all of its methods. Classes IbfRP#### extend IbfReport, and contain only those methods unique to a particular report. If a change is made in IbfReport, it is reflected in the IbfRP#### programs (classes) the next time they are run.
COBOL: ON EXCEPTION
Java: try/throw/catch
++: can limit scope of error detection (see following)
COBOL: OPEN
Java: Input Streams
++: Automatic error detection, both a blessing and a curse.
COBOL: WRITE
Java: write (yes, really).
COBOL: CLOSE
Java: close method
COBOL: READ
Java: read...
As the question says, what are some common/major issues that C++ programmers face when switching to Java? I am looking for some broad topic names or examples and day to day adjustments that engineers had to make. I can then go and do an in-depth reading on this.
I am specifically interested in opinions of engineers who have worked in C++ for years and had to work with Java but any pointers from others or even book recommendations are more than welcome.
In C++ you'd use destructors to clean up file descriptors, database connections and the like. The naive equivalent is to use finalizers. Don't. Ever.
Instead use this pattern:
OutputStream os;
try {
os = ...
// do stuff
} finally {
try { os.close(); } catch (Exception e) { }
}
You'll end up doing stuff like that a lot.
If you specify no access modifer, in Java the members are package-private by default, unlike C++ in which they are private. Package-private is an annoying access level meaning it's private but anything in the same package can access it too (which is an idiotic default access level imho);
There is no stack/heap separation. Everything is created on the heap (well, that's not strictly true but we'll pretend it is);
There is no pass-by-reference;
The equivalent to function pointers is anonymous interfaces.
My biggest hurdle crossing from C++ to Java was ditching procedural code. I was very used to tying all my objects together within procedures. Without procedural code in java, I made circular references everywhere. I had to learn how to call objects from objects without them being dependents of each other. It was the Biggest hurdle but the easiest to overcome.
Number 2 personal issue is documentation. JavaDoc is useful but to many java projects are under the misconception that all that is needed is the JavaDoc. I saw much better documentation in C++ projects. This may just be a personal preference for documentation outside of the code.
Number 3. There are in fact pointers in java, just no pointer arithmetic. In java they are called references. Don't think that you can ignore where things are pointing at, it will come back with a big bite.
== and .equals are not equal.
== will look at the pointer(reference) while .equals will look at the value that the reference is pointing at.
Generics (instead of templates), specifically the way they were implemented using type erasure.
Since you mention book recommendations, definitely read Effective Java, 2nd ed.—it addresses most of the pitfalls I've seen listed in the answers.
Creating a reference by accident when one was thinking of a copy constructor:
myClass me = new myClass();
myClass somebodyElse = me; /* A reference, not a value copied into an independent instance! */
somebodyElse.setPhoneNumber(5551234);
/* Hey... how come my phone doesn't work anymore?!?!? */
No multiple inheritance, and every class implicitly derives from java.lang.Object (which has a number of important methods you definitely have to know and understand)
You can have a sort of multiple inheritance by implementing interfaces
No operator overloading except for '+' (for Strings), and definitely none you can do yourself
No unsigned numerical types, except char, which shouldn't really be used as a numerical type. If you have to deal with unsigned types, you have to do a lot of casting and masking.
Strings are not null-terminated, instead they are based on char arrays and as such are immutable. As a consequence of this, building a long String by appending with += in a loop is O(n^2), so don't do it; use a StringBuilder instead.
Getting used to having a garbage collector. Not being able to rely on a destructor to clean up resources that the GC does not handle.
Everything is passed by value, because references are passed instead of objects.
No copy constructor, unless you have a need to clone. No assignment operator.
All methods are virtual by default, which is the opposite of C++.
Explicit language support for interfaces - pure virtual classes in C++.
It's all the little bitty syntax differences that got me. Lack of destructors.
On the other hand, being able to write a main for each class (immensely handy or testing) is real nice; after you get used to it, the structure and tricks available with jar files are real nice; the fact that the semantics are completely defined (eg, int is the same everywhere) is real nice.
My worst problem was keeping in mind the ownership of memory at all times. In C++, it's a necessary thing to do, and it creates some patterns in developer's mind that are hard to overcome. In Java, I can forget about it (to a very high degree, anyway), and this enables some algorithms and approaches that would be exceedingly awkward in C++.
There are no objects in Java, there are only references to objects. E.g :
MyClass myClass; // no object is created unlike C++.
But :
MyClass myClass = new MyClass(); // Now it is a valid java object reference.
The best book of Java "gotchas" that I've read is Java Puzzlers: Traps, Pitfalls, and Corner Cases. It's not specifically aimed at C++ developers, but it is full of examples of things you want to look out for.
Specifying a method parameter as final doesn't mean what you at first think it means
private void doSomething(final MyObject myObj){
...
myObj.setSomething("this will change the obj in the calling method too");
...
}
because java is pass by value it is doing what you're asking, just not immediately obvious unless you understand how java passes the value of the reference rather than the object.
Another notable one is the keyword final and const. Java defines the const as a reserved keyword but doesn't specify much of its usage. Also
object1=object2
doesn't copy the objects it changes the reference
All methods are virtual.
Parameterized types (generics) don't actually create code parameter-specific code (ie, List<String> uses the same bytecode as List<Object>; the compiler is the only thing that complains if you try to put an Integer in the former).
Varargs is easy.