This question already has answers here:
Closed 13 years ago.
In C++ we have the Resource Acquisition Is Initialization (RAII) pattern, which greatly simplifies resource management. The idea is to provide some wrapping object for any kind of resources. The wrapping object's destructor is then responsible for releasing the resources, when it goes out of its scope. For example:
{
auto_ptr<int> smartPointer = new int;
// some other code
} // the memory allocated for the int is released automatically
// by smartPointer's destructor
The most common usage are smart pointers. But, there are many other kinds of resources (files, mutexes, sockets, etc.) which can be managed exactly the same way.
In Java one doesn't have to bother the memory management. But all other types of resources remain. There is finally block, but its usage is quite inconvenient, especially when many different exceptions can be thrown.
So, my question is if there is any Java pattern which provides functionality equivalent to C++ RAII? If not, please share your best practices in this area (instead of the finally, unless it's used some sophisticated way).
You can use the usual acquire; try { use; } finally { release; }. Alternatively you can abstract the resource handling with the Execute Around idiom.
Joshua Bloch has proposed adding a mechanism called Automatic Resource Management to Java as part of Project Coin (small language changes for JDK 7):
The nearest equivalent is try/finally, see http://java.sun.com/docs/books/tutorial/essential/exceptions/finally.html
To many coders, the strength of the RAII idiom is that the life of the underlying resource is tied to a scope block, making things simpler to make and maintain; ultimately reducing errors from failing to release that resource.
Unfortunately you can't mimic this behaviour in Java as you can't create your own scope-bound structures. A language similar to Java that has tried to solve this problem is C#:
// explicit release
MyClass obj = MyClass();
obj.UseIt();
obj.Dispose();
// RAII-like (scope-bound) release
using(MyClass obj = new MyClass())
{
obj.UseIt();
}
Perhaps we'll see functionality like this implemented in future.
Related
Java's AutoCloseable feature "reuses" try/catch semantics:
try (Stream x = ...) {
// work with x
}
// x is out of scope and was auto-closed
I'm curious why they didn't introduce new semantics for this new feature. try implies that you expect the body to throw an exception at one point or another (or that it may). This seems much different to me than "instantiate this resource and close it when I'm done". That doesn't have anything to do with handling exceptions. Why not something like this...
with (Stream x = ...) { ... }
using (Stream x = ...) { ... } // I know, C# syntax
I'm not looking to fuel a debate, I want to know the reason the Java team decided to re-use try for this feature.
Java always tries its best to be backwards compatible. It's the cause of pretty much all of the weird or unfortunate aspects of the language today. It's happened a handful of times, but introducing a new keyword such as with or using was not a decision to be taken lightly. If they'd introduced a new keyword using, old code such as int using = 0 would not compile against the latest version of Java*
try-with-resources was basically introduced to reduce the verbosity of the following common pattern:
SomeResource resource;
try {
resource = new Resource();
resource.foo();
}
//optional catch
finally {
if (resource != null) resource.close();
}
Because try was already involved before, adding additional functionality to try was the logical happy medium.
* Interestingly, a similar discussion was had over Java 10's var, which is not actually a keyword but a 'reserved type name' (so the semantics are slightly different):
Risk: source incompatibilities (someone may have used var as a type
name.)
The question is partially about a design choice in the Java language. Due to the nature of the question, this answer is only a partial answer of the question.
The try-with-resources does not reuse the try-catch concept, but the try-finally concept. Although seldom seen, try-finally has its uses. You could, for example, instead of explicitly catching an exception and re-throwing it, simply do some cleanup in the finally-block.1
The nature of AutoCloseable resources fits quite nicely in this use case: Open an AutoCloseable resource, do something and at the end close it, no matter what.
One could argue that starting this process through a try seems artificial. This, however, was a design decision of the language committe and is therefore not up to debate. If I had to guess, I would go with Michael's line of argumentation and say that they did not want to introduce a new keyword to stay backwards compatible.
1I am aware of the fact that was pointed out by #Radiodef, that a try-with-resources will be translated to a try-catch-finally. From my point of view, however, this is an implementation detail and a tool to specify the behaviour. It is not essential for understanding the semantics.
This question already has answers here:
Java double checked locking
(11 answers)
Closed 8 years ago.
There's a common belief and multiple sources (including wiki) that claim this idiom to be an anti-pattern.
What are the arguments against using it in production code given the correct implementation is used (for example, using volatile)
What are the appropriate alternatives for implementing lazy initialization in a multithreaded environment ? Locking the whole method may become a bottleneck and even while modern synchronization is relatively cheap, it's still much slower especially under contention. Static holder seems to be a language-specific and a bit ugly hack (at least for me). Atomics-based implementation seems not be so different from traditional DCL while allowing multiple calculations or requires more complicated code. For example, Scala is still using DCL for implementing the lazy values while proposed alternative seems to be much more complicated.
Don't use double checked locking. Ever. It does not work. Don't try to find a hack to make it work, because it may not on a later JRE.
As far as I know, there is no other save way for lazy initialization than locking the whole object / synchronizing.
synchronized (lock) {
// lookup
// lazy init
}
For singletons the static holder (as #trashgod mentioned) is nice, but will not remain single if you have multiple classloaders.
If you require a lazy singleton in a multi-classloader environment, use the ServiceLoader.
I am wondering about how unsafe the use sun.misc.Unsafe actually is. I want to create a proxy of an object where I intercept every method call (but the one to Object.finalize for performance considerations). For this purpose, I googled a litle bit and came up with the following code snippet:
class MyClass {
private final String value;
MyClass() {
this.value = "called";
}
public void print() {
System.out.println(value);
}
}
#org.junit.Test
public void testConstructorTrespassing() throws Exception {
#SuppressWarnings("unchecked")
Constructor<MyClass> constructor = ReflectionFactory.getReflectionFactory()
.newConstructorForSerialization(MyClass.class, Object.class.getConstructor());
constructor.setAccessible(true);
assertNull(constructor.newInstance().print());
}
My consideration is:
Even though Java is advertised as Write once, run everywhere my reality as a developer looks rather like Write once, run once in a controllable customer's run time environment
sun.misc.Unsafe is considered to become part of the public API in Java 9
Many non-Oracle VMs also offer sun.misc.Unsafe since - I guess - there are quite some libraries already use it. This also makes the class unlikely to disappear
I am never going to run the application on Android, so this does not matter for me.
How many people are actually using non-Oracle VMs anyways?
I am still wondering: Are there other reasons why I should not use sun.misc.Unsafe I did not think of? If you google this questions, people rather answer an unspecified because its not safe but I do not really feel it is besides of the (very unlikely) possibility that the method will one day disappear form the Oracle VM.
I actually need to create an object without calling a constructor to overcome Java's type system. I am not considering sun.misc.Unsafe for performance reasons.
Additional information: I am using ReflectionFactory in the example for convenience which delegates to Unsafe eventually. I know about libraries like objenesis but looking at the code I found out that they basically do something similar but check for other ways when using Java versions which would not work for me anyways so I guess writing four lines is worth saving a dependency.
There are three significant (IMO) issues:
The methods in the Unsafe class have the ability to violate runtime type safety, and do other things that can lead to your JVM "hard crashing".
Virtually anything that you do using Unsafe could in theory be dependent on internal details of the JVM; i.e. details of how the JVM does things and represents things. These may be platform dependent, and may change from one version of Java to the next.
The methods you are using ... or even the class name itself ... may not be the same across different releases, platforms and vendors.
IMO, these amount to strong reasons not to do it ... but that is a matter of opinion.
Now if Unsafe becomes standardised / part of the standard Java API (e.g. in Java 9), then some of the above issues would be moot. But I think the risk of hard crashes if you make a mistake will always remain.
During one JavaOne 2013 session Mark Reinhold (the JDK architect) got a question: "how safe it is to use the Unsafe class?". He replied with sort of surprising answer: "I believe its should become a stable API. Of course properly guarded with security checks, etc..."
So it looks like there may be something like java.util.Unsafe for JDK9. Meanwhile using the existing class is relatively safe (as safe as doing something unsafe can be).
I'm going to reuse OGNL library out of Struts2 scope. I have rather large set of formulas, that is why I would like to precompile all of them:
Ognl.parseExpression(expressionString);
But I'm not sure if precompiled expression can be used in multi-thread environment. Does anybody knows if it can be used?
This PropertyUtils code from OGNL is written to be thread-safe, and so I would guess that compiled expressions are intended to be thread safe.
Further evidence is that most of the accessor API provide the mutable state as a context parameter (e.g. see PropertyAccessor), so the classes themselves have little mutable state. Immutable classes are intrinsicly thread-safe. The developer guide urges extensions to be thread-safe, and finally
looking through the code, where there is mutable state, it is guarded in a synchronized block, for example see EvaluationPool.
In summary, it seems OGNL has been designed to be thread-safe. Whether it actually is or not is another question! You could write a quick test to see for sure, using for example Concutest. Alternatively, if the number of threads is reasonable, storing all the expressions in a ThreadLocal sidesteps the issue altogether, at the cost of a little extra memory (or possibly not, as OGNL does expression caching.)
I think your best option is to contact original developers, directly or through mailing list:
http://www.opensymphony.com/ognl/members.action
https://ognl.dev.java.net/servlets/ProjectMailingListList
The project seems to be abandoned for some time, so there is hardly anybody else who knows :/
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.