I have a class of which there may be many instances (on a mobile device), so I'm trying to minimize the size. One of my fields is a "DrawTarget" that indicates whether drawing operations are being ignored, queued to a path or drawn to the display. I would like it to take a single byte or less since there are only 3 possible values, but I would also like it to be friendly code so I don't have hard-coded numbers all over. One thought is to use an enum like:
public enum DrawTarget {
Invisible,
Path,
Canvas
}
But from what I read, a Java enum doesn't allow you to specify the memory layout -- I can't request that the enum values represent a byte-size value -- and I guess enum values end up being integer-sized values in Java.
So I thought about maybe making an implicit conversion operator in the enum... is this possible in Java? Or is my best option to implement something like this within the enum:
public static DrawTarget fromValue(byte value) {
switch (value) {
case 0:
return Invisible;
case 1:
return Path;
default:
return Canvas;
}
}
and then call DrawTarget.fromValue wherever I want to access the value?
Or should I just create a single-byte class since apparently (from what I read in my research on this) enums are basically just special classes in Java anyway?
public class DrawTarget {
public static final byte Invisible = 0;
public static final byte Path = 1;
public static final byte Canvas = 2;
}
But how to I represent the value of an enum instance if I use that last solution? I still need a way to allow the "=" operator to accept one of the static fields of the class... like a conversion constructor or an assignment operator overload.
I suspect, however, that any class object, being a reference type, will take more than a byte for each instance. Is that true?
In Java enum is a class that has as many instances, as there are values. The instances are produced at class (enum) loading time. Each place where you use an enum variable or an enum attribute, you actually use an ordinary reference to one of the existing enum objects (instances of enums are never created after enum is initialized).
This means that an enum reference costs as much as any other object reference, usually four bytes. Which is really, really, really little.
You don't know how much memory does a byte take (really! remember that low level memory management includes plenty of padding!), so any "optimization" based on this will fail. On a given architecture a byte field might take as much memory as an integer field (because it might be faster that way).
If you want to write good Java, use enum. Really. The only good reason not to use enums, would be if you had a whole array of values, like: drawTargets[] = new DrawTarget[100000];
If you insist on microoptimizing, just use plain bytes and forget enums; public static final byte SOMETHING = 1; is fine for making comparisons (and sucks for debugging).
I have written Android programs for a long time and have never seen such microoptimization pay off. Your case might be the one in a million, but I don't think it is.
Also, to make life simpler for all of us, please consider using Java conventions in Java code: enum instances and public final static fields should be names LIKE_THIS, attributes likeThis (not LikeThis!).
and I guess enum values end up being integer-sized values in Java.
No, enums are always classes in Java. So if you have a field of type DrawTarget, that will be a reference - either to null or to one of the three instances of DrawTarget. (There won't be any more instances than that; it's not like a new instance of DrawTarget is created every time you use it.)
I would go with the enum and then measure the memory usage - an enum is logically what you want, so take the normal approach of writing the simplest code that works and then testing the performance - rather than guessing at where bottlenecks might be.
You may want to represent the value as a single byte when serializing, and then convert it back to the enum when deserializing, but other than that I'd stick with the enum type throughout your code if possible.
Unless android has some special way of treating enum references, each reference to a DropTarget will indeed take more than one byte in memory. Enums are classes, and enum instances are objects. So a reference to an enum instance takes the same amout of memory as any other object reference.
I wouldn't care much about it unless you have measured that this caused memory problems, though, and that reducing the size would have a significant impact.
What you get from enums, mainly, is type safety. If a method takes a DropTarget as argument, you (or coworkers) won't be able to pass anything other than one of the three instances of DropTarget (or null). If you use a byte instead, the code is less clear, and anyone could pass any byte value instead of the three authorized byte values.
So, decide which is the most important for you, and choose the solution you prefer.
Your classes will only contain a reference to the enum. Only one instance of each enum will be created.
Aside from that, consider using polymorphism to implement the drawing behavior.
If the value of the enum is fixed, instantiate a different subclass for each object depending on its desired drawing behavior.
If the value changes often, you could keep a reference to the desired drawing strategy in the object. Refer to an object with an empty draw() method for objects that should not be drawn. Etc.
enum is special data type, not a class.check oracle documentations for further details.
An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it.
Related
I am aware there are similar questions, and I have read the answers, but maybe I'm just not quite grasping the full difference of its use, even though I understand their difference when for example, initializing a String. Example:
String[] favorite = {"dog", "cat", "alien"};
vs
enum favorite = {dog, cat, alien}
Or maybe the use of either in the above case is similar, but their difference can be grasped better in another example? Is it that enum can clearly store more properties for a variable when creating the class?
The big advantage of enum is that the compiler checks for typos (type safety). For instance, if you assign the value "dag" to a string, the compiler does not complain. But, you cannot assign the value favorite.dag to a variable (of type favorit). Also, enum makes the code more readable and it is faster (comparison, for instance).
Just like #AhmadWabbi said, it's mostly type safety.
With enums you also have the ability to write methods corresponding to the enum.
For instance:
public enum Favorite = {
dog("woof"),
cat("meow"),
alien("zoink")
private String sound;
Favorite(String sound) {
this.sound = sound;
}
public String makeSound() {
return sound;
}
}
Which then let you call the method on a known enum (Favorite.dog.makeSound()) or if the enum is a parameter to another method.
The biggest advantage is that an enum is type-safe. An enum value can only take on one of the defined values (or null). (Note that an enum in Java is not like an enum in C++ or C#, where it is more like an alias for an int).
If you use a type like String or int, you can assign to that any value that fits in a String or int, even if it's not one of the limited set of values that you want it to contain.
It also makes programs easier to read, because when for example a method takes an enum type as a parameter, you immediately know what it means, and what values are valid - if it would, for example, take a String, you don't automatically know which strings are valid inputs and which are not.
There is no need to be too sophisticated with a program.
If you have three strings use the string array. If you have three distinct entities which differ by something else in addition to their names, use enum (on which you, evidently, will then be operating somehow).
Enums are easy to add new functionality to your code. Strings have their limits, you can decide yourself if you need all the benefits of enums or string will do for the job.
For example:
public enum favourite {
dog, cat, cow;
public boolean barking(){
switch(this){
case dog:
return true;
case cat:
case cow:
return false;
}
throw new AssertionError();
}
}
Enum sort of create a namespace . Thus two constants with same name can belong to different enums. Of course , you can emulate it with ArrayList but its not intuitive , because its supposed to acts as a container rather than a logical namespace holding constants.
You can compare it old style enums from C++ , where two enum declarations holding a same named constant shows a error . With new style class enums in c++ adds sort of namespace to it , which was not possible earlier.
And yes
Enums in Java already have a name-spacing feature.
By the way , Enum and ArrayList both have different purpose.
The biggest advantage of enums is that they are type-safe: a variable of an enum type can only hold values defined in that enum. By the way, in some circumstances this can be a big disadvantage, a show-stopper even: if the possible values are not known at compile time (for example, because you need to fetch them from a database at run-time) you cannot use enums.
Although I do not see a clear advantage of it (and if I don't see a clear advantage I would always use the established coding practice, which is using an enum), you can certainly use strings as a kind of enums. Performance will probably be a bit worse because of the string comparisons, but in most cases unnoticeably so.
However, I would strictly advice against your array example, for the following reasons:
Arrays are mutable. If your project is large enough, someone will eventually write favorites[0] = "beer"; and thus cause mysterious bugs in unrelated parts of the code.
Using an array has no advantage in readability. The meaning String myFavorite = favorites[1]; is completely opaque, whereas String myFavorite = "cat"; or Favorite myFavorite = Favorite.CAT; are immediately clear.
String literals can be used in switch statements, but not expressions like favorites[2]. So switch (myFavorite) { case favorites[2]: ... } is not legal Java (whereas switch (myFavorite) { case "alien": ... } is).
If you really want to use Strings as enums, then define String constants:
public static final String FAV_DOG = "dog";
public static final String FAV_CAT = "cat";
public static final String FAV_ALIEN = "alien";
I am unable to get what are the scenarios where we need an immutable class.
Have you ever faced any such requirement? or can you please give us any real example where we should use this pattern.
The other answers seem too focused on explaining why immutability is good. It is very good and I use it whenever possible. However, that is not your question. I'll take your question point by point to try to make sure you're getting the answers and examples you need.
I am unable to get what are the scenarios where we need an immutable class.
"Need" is a relative term here. Immutable classes are a design pattern that, like any paradigm/pattern/tool, is there to make constructing software easier. Similarly, plenty of code was written before the OO paradigm came along, but count me among the programmers that "need" OO. Immutable classes, like OO, aren't strictly needed, but I going to act like I need them.
Have you ever faced any such requirement?
If you aren't looking at the objects in the problem domain with the right perspective, you may not see a requirement for an immutable object. It might be easy to think that a problem domain doesn't require any immutable classes if you're not familiar when to use them advantageously.
I often use immutable classes where I think of a given object in my problem domain as a value or fixed instance. This notion is sometimes dependent on perspective or viewpoint, but ideally, it will be easy to switch into the right perspective to identify good candidate objects.
You can get a better sense of where immutable objects are really useful (if not strictly necessary) by making sure you read up on various books/online articles to develop a good sense of how to think about immutable classes. One good article to get you started is Java theory and practice: To mutate or not to mutate?
I'll try to give a couple of examples below of how one can see objects in different perspectives (mutable vs immutable) to clarify what I mean by perspective.
... can you please give us any real example where we should use this pattern.
Since you asked for real examples I'll give you some, but first, let's start with some classic examples.
Classic Value Objects
Strings and integers are often thought of as values. Therefore it's not surprising to find that String class and the Integer wrapper class (as well as the other wrapper classes) are immutable in Java. A color is usually thought of as a value, thus the immutable Color class.
Counterexample
In contrast, a car is not usually thought of as a value object. Modeling a car usually means creating a class that has changing state (odometer, speed, fuel level, etc). However, there are some domains where it car may be a value object. For example, a car (or specifically a car model) might be thought of as a value object in an app to look up the proper motor oil for a given vehicle.
Playing Cards
Ever write a playing card program? I did. I could have represented a playing card as a mutable object with a mutable suit and rank. A draw-poker hand could be 5 fixed instances where replacing the 5th card in my hand would mean mutating the 5th playing card instance into a new card by changing its suit and rank ivars.
However, I tend to think of a playing card as an immutable object that has a fixed unchanging suit and rank once created. My draw poker hand would be 5 instances and replacing a card in my hand would involve discarding one of those instance and adding a new random instance to my hand.
Map Projection
One last example is when I worked on some map code where the map could display itself in various projections. The original code had the map use a fixed, but mutatable projection instance (like the mutable playing card above). Changing the map projection meant mutating the map's projection instance's ivars (projection type, center point, zoom, etc).
However, I felt the design was simpler if I thought of a projection as an immutable value or fixed instance. Changing the map projection meant having the map reference a different projection instance rather than mutating the map's fixed projection instance. This also made it simpler to capture named projections such as MERCATOR_WORLD_VIEW.
Immutable classes are in general much simpler to design, implement and use correctly. An example is String: the implementation of java.lang.String is significantly simpler than that of std::string in C++, mostly due to its immutability.
One particular area where immutability makes an especially big difference is concurrency: immutable objects can safely be shared among multiple threads, whereas mutable objects must be made thread-safe via careful design and implementation - usually this is far from a trivial task.
Update: Effective Java 2nd Edition tackles this issue in detail - see Item 15: Minimize mutability.
See also these related posts:
non-technical benefits of having string-type immutable
Downsides to immutable objects in Java?
Effective Java by Joshua Bloch outlines several reasons to write immutable classes:
Simplicity - each class is in one state only
Thread Safe - because the state cannot be changed, no synchronization is required
Writing in an immutable style can lead to more robust code. Imagine if Strings weren't immutable; Any getter methods that returned a String would require the implementation to create a defensive copy before the String was returned - otherwise a client may accidentally or maliciously break that state of the object.
In general it is good practise to make an object immutable unless there are severe performance problems as a result. In such circumstances, mutable builder objects can be used to build immutable objects e.g. StringBuilder
Hashmaps are a classic example. It's imperative that the key to a map be immutable. If the key is not immutable, and you change a value on the key such that hashCode() would result in a new value, the map is now broken (a key is now in the wrong location in the hash table.).
Java is practically one and all references. Sometimes an instance is referenced multiple times. If you change such an instance, it would be reflected into all its references. Sometimes you simply don't want to have this to improve robustness and threadsafety. Then an immutable class is useful so that one is forced to create a new instance and reassign it to the current reference. This way the original instance of the other references remain untouched.
Imagine how Java would look like if String was mutable.
Let's take an extreme case: integer constants. If I write a statement like "x=x+1" I want to be 100% confidant that the number "1" will not somehow become 2, no matter what happens anywhere else in the program.
Now okay, integer constants are not a class, but the concept is the same. Suppose I write:
String customerId=getCustomerId();
String customerName=getCustomerName(customerId);
String customerBalance=getCustomerBalance(customerid);
Looks simple enough. But if Strings were not immutable, then I would have to consider the possibility that getCustomerName could change customerId, so that when I call getCustomerBalance, I am getting the balance for a different customer. Now you might say, "Why in the world would someone writing a getCustomerName function make it change the id? That would make no sense." But that's exactly where you could get in trouble. The person writing the above code might take it as just obvious that the functions would not change the parameter. Then someone comes along who has to modify another use of that function to handle the case where where a customer has multiple accounts under the same name. And he says, "Oh, here's this handy getCustomer name function that's already looking up the name. I'll just make that automatically change the id to the next account with the same name, and put it in a loop ..." And then your program starts mysteriously not working. Would that be bad coding style? Probably. But it's precisely a problem in cases where the side effect is NOT obvious.
Immutability simply means that a certain class of objects are constants, and we can treat them as constants.
(Of course the user could assign a different "constant object" to a variable. Someone can write
String s="hello";
and then later write
s="goodbye";
Unless I make the variable final, I can't be sure that it's not being changed within my own block of code. Just like integer constants assure me that "1" is always the same number, but not that "x=1" will never be changed by writing "x=2". But I can be confidant that if I have a handle to an immutable object, that no function I pass it to can change it on me, or that if I make two copies of it, that a change to the variable holding one copy will not change the other. Etc.
We don't need immutable classes, per se, but they can certainly make some programming tasks easier, especially when multiple threads are involved. You don't have to perform any locking to access an immutable object, and any facts that you've already established about such an object will continue to be true in the future.
There are various reason for immutability:
Thread Safety: Immutable objects cannot be changed nor can its internal state change, thus there's no need to synchronise it.
It also guarantees that whatever I send through (through a network) has to come in the same state as previously sent. It means that nobody (eavesdropper) can come and add random data in my immutable set.
It's also simpler to develop. You guarantee that no subclasses will exist if an object is immutable. E.g. a String class.
So, if you want to send data through a network service, and you want a sense of guarantee that you will have your result exactly the same as what you sent, set it as immutable.
My 2 cents for future visitors:
2 scenarios where immutable objects are good choices are:
In multi-threading
Concurrency issues in multi-threaded environment can very well be solved by synchronization but synchronization is costly affair (wouldn't dig here on "why"), so if you are using immutable objects then there is no synchronization to solve concurrency issue because state of immutable objects cannot be changed, and if state cannot be changed then all threads can seamless access the object. So, immutable objects makes a great choice for shared objects in multi-threaded environment.
As key for hash based collections
One of the most important thing to note when working with hash based collection is that key should be such that its hashCode() should always return the same value for the lifetime of the object, because if that value is changed then old entry made into the hash based collection using that object cannot be retrieved, hence it would cause memory leak. Since state of immutable objects cannot be changed so they makes a great choice as key in hash based collection. So, if you are using immutable object as key for hash based collection then you can be sure that there will not be any memory leak because of that (of course there can still be memory leak when the object used as key is not referenced from anywhere else, but that's not the point here).
I'm going to attack this from a different perspective. I find immutable objects make life easier for me when reading code.
If I have a mutable object I am never sure what its value is if it's ever used outside of my immediate scope. Let's say I create MyMutableObject in a method's local variables, fill it out with values, then pass it to five other methods. ANY ONE of those methods can change my object's state, so one of two things has to occur:
I have to keep track of the bodies of five additional methods while thinking about my code's logic.
I have to make five wasteful defensive copies of my object to ensure that the right values get passed to each method.
The first makes reasoning about my code difficult. The second makes my code suck in performance -- I'm basically mimicking an immutable object with copy-on-write semantics anyway, but doing it all the time whether or not the called methods actually modify my object's state.
If I instead use MyImmutableObject, I can be assured that what I set is what the values will be for the life of my method. There's no "spooky action at a distance" that will change it out from under me and there's no need for me to make defensive copies of my object before invoking the five other methods. If the other methods want to change things for their purposes they have to make the copy – but they only do this if they really have to make a copy (as opposed to my doing it before each and every external method call). I spare myself the mental resources of keeping track of methods which may not even be in my current source file, and I spare the system the overhead of endlessly making unnecessary defensive copies just in case.
(If I go outside of the Java world and into, say, the C++ world, among others, I can get even trickier. I can make the objects appear as if they're mutable, but behind the scenes make them transparently clone on any kind of state change—that's copy-on-write—with nobody being the wiser.)
Immutable objects are instances whose states do not change once initiated.
The use of such objects is requirement specific.
Immutable class is good for caching purpose and it is thread safe.
By the virtue of immutability you can be sure that the behavior/state of the underlying immutable object do not to change, with that you get added advantage of performing additional operations:
You can use multiple core/processing(concurrent/parallel processing) with ease(as the sequence of operations will no longer matter.)
Can do caching for expensive operations (as you are sure of the same
result).
Can do debugging with ease(as the history of run will not be a concern
anymore)
Using the final keyword doesn't necessarily make something immutable:
public class Scratchpad {
public static void main(String[] args) throws Exception {
SomeData sd = new SomeData("foo");
System.out.println(sd.data); //prints "foo"
voodoo(sd, "data", "bar");
System.out.println(sd.data); //prints "bar"
}
private static void voodoo(Object obj, String fieldName, Object value) throws Exception {
Field f = SomeData.class.getDeclaredField("data");
f.setAccessible(true);
Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.set(obj, "bar");
}
}
class SomeData {
final String data;
SomeData(String data) {
this.data = data;
}
}
Just an example to demonstrate that the "final" keyword is there to prevent programmer error, and not much more. Whereas reassigning a value lacking a final keyword can easily happen by accident, going to this length to change a value would have to be done intentionally. It's there for documentation and to prevent programmer error.
Immutable data structures can also help when coding recursive algorithms. For example, say that you're trying to solve a 3SAT problem. One way is to do the following:
Pick an unassigned variable.
Give it the value of TRUE. Simplify the instance by taking out clauses that are now satisfied, and recur to solve the simpler instance.
If the recursion on the TRUE case failed, then assign that variable FALSE instead. Simplify this new instance, and recur to solve it.
If you have a mutable structure to represent the problem, then when you simplify the instance in the TRUE branch, you'll either have to:
Keep track of all changes you make, and undo them all once you realize the problem can't be solved. This has large overhead because your recursion can go pretty deep, and it's tricky to code.
Make a copy of the instance, and then modify the copy. This will be slow because if your recursion is a few dozen levels deep, you'll have to make many many copies of the instance.
However if you code it in a clever way, you can have an immutable structure, where any operation returns an updated (but still immutable) version of the problem (similar to String.replace - it doesn't replace the string, just gives you a new one). The naive way to implement this is to have the "immutable" structure just copy and make a new one on any modification, reducing it to the 2nd solution when having a mutable one, with all that overhead, but you can do it in a more efficient way.
One of the reasons for the "need" for immutable classes is the combination of passing everything by reference and having no support for read-only views of an object (i.e. C++'s const).
Consider the simple case of a class having support for the observer pattern:
class Person {
public string getName() { ... }
public void registerForNameChange(NameChangedObserver o) { ... }
}
If string were not immutable, it would be impossible for the Person class to implement registerForNameChange() correctly, because someone could write the following, effectively modifying the person's name without triggering any notification.
void foo(Person p) {
p.getName().prepend("Mr. ");
}
In C++, getName() returning a const std::string& has the effect of returning by reference and preventing access to mutators, meaning immutable classes are not necessary in that context.
They also give us a guarantee. The guarantee of immutability means that we can expand on them and create new patters for efficiency that are otherwise not possible.
http://en.wikipedia.org/wiki/Singleton_pattern
One feature of immutable classes which hasn't yet been called out: storing a reference to a deeply-immutable class object is an efficient means of storing all of the state contained therein. Suppose I have a mutable object which uses a deeply-immutable object to hold 50K worth of state information. Suppose, further, that I wish to on 25 occasions make a "copy" of my original (mutable) object (e.g. for an "undo" buffer); the state could change between copy operations, but usually doesn't. Making a "copy" of the mutable object would simply require copying a reference to its immutable state, so 20 copies would simply amount to 20 references. By contrast, if the state were held in 50K worth of mutable objects, each of the 25 copy operations would have to produce its own copy of 50K worth of data; holding all 25 copies would require holding over a meg worth of mostly-duplicated data. Even though the first copy operation would produce a copy of the data that will never change, and the other 24 operations could in theory simply refer back to that, in most implementations there would be no way for the second object asking for a copy of the information to know that an immutable copy already exists(*).
(*) One pattern that can sometimes be useful is for mutable objects to have two fields to hold their state--one in mutable form and one in immutable form. Objects can be copied as mutable or immutable, and would begin life with one or the other reference set. As soon as the object wants to change its state, it copies the immutable reference to the mutable one (if it hasn't been done already) and invalidates the immutable one. When the object is copied as immutable, if its immutable reference isn't set, an immutable copy will be created and the immutable reference pointed to that. This approach will require a few more copy operations than would a "full-fledged copy on write" (e.g. asking to copy an object which has been mutated since the last copy would require a copy operation, even if the original object is never again mutated) but it avoids the threading complexities that FFCOW would entail.
Why Immutable class?
Once an object is instantiated it state cannot be changed in lifetime. Which also makes it thread safe.
Examples :
Obviously String, Integer and BigDecimal etc. Once these values are created cannot be changed in lifetime.
Use-case :
Once Database connection object is created with its configuration values you might not need to change its state where you can use an immutable class
from Effective Java;
An immutable class is simply a class whose instances cannot be modified. All of
the information contained in each instance is provided when it is created and is
fixed for the lifetime of the object. The Java platform libraries contain many
immutable classes, including String, the boxed primitive classes, and BigInte-
ger and BigDecimal. There are many good reasons for this: Immutable classes
are easier to design, implement and use than mutable classes. They are less prone
to error and are more secure.
An immutable class is good for caching purposes because you don't have to worry about the value changes. Another benefit of an immutable class is that it is inherently thread-safe, so you don't have to worry about thread safety in case of a multi-threaded environment.
I need to pass a dynamic list of primitives to a Java method. That could be (int, int, float) or (double, char) or whatever. I know that's not possible, so I was thinking of valid solutions to this problem.
Since I am developing a game on Android, where I want to avoid garbage collection as much as possible, I do not want to use any objects (e.g. because of auto boxing), but solely primitive data types. Thus a collection or array of primitive class objects (e.g. Integer) is not an option in my case.
So I was thinking whether I could pass a class object to my method, which would contain all the primitive vales I need. However, thats neither a solution to my problem, because as said the list of primitives is variable. So if I would go that way in my method I then don't know how to access this dynmic list of primitives (at least not without any conversion to objects, which is what I want to avoid).
Now I feel a bit lost here. I do not know of any other possible way in Java how to solve my problem. I hope that's simply a lack of knowledge on my side. Does anyone of you know a solution without a conversion to and from objects?
It would perhaps be useful to provide some more context and explain on exactly what you want to use this technique for, since this will probably be necessary to decide on the best approach.
Conceptually, you are trying to do something that is always difficult in any language that passes parameters on a managed stack. What do you expect the poor compiler to do? Either it lets you push an arbitrary number of arguments on the stack and access them with some stack pointer arithmetic (fine in C which lets you play with pointers as much as you like, not so fine in a managed language like Java) or it will need to pass a reference to storage elsewhere (which implies allocation or some form of buffer).
Luckily, there are several ways to do efficient primitive parameter passing in Java. Here is my list of the most promising approaches, roughly the order you should consider them:
Overloading - have multiple methods with different primitive arguments to handle all the possible combinations. Likely to be the the best / simplest / most lightweight option if there are a relatively small number of arguments. Also great performance since the compiler will statically work out which overloaded method to call.
Primitive arrays - Good way of passing an arbitrary number of primitive arguments. Note that you will probably need to keep a primitive array around as a buffer (otherwise you will have to allocate it when needed, which defeats your objective of avoiding allocations!). If you use partially-filled primitive arrays you will also need to pass offset and/or count arguments into the array.
Pass objects with primitive fields - works well if the set of primitive fields is relatively well known in advance. Note that you will also have to keep an instance of the class around to act as a buffer (otherwise you will have to allocate it when needed, which defeats your objective of avoiding allocations!).
Use a specialised primitive collection library - e.g. the Trove library. Great performance and saves you having to write a lot of code as these are generally well designed and maintained libraries. Pretty good option if these collections of primitives are going to be long lived, i.e. you're not creating the collection purely for the purpose of passing some parameters.
NIO Buffers - roughly equivalent to using arrays or primitive collections in terms of performance. They have a bit of overhead, but could be a better option if you need NIO buffers for another reason (e.g. if the primitives are being passed around in networking code or 3D library code that uses the same buffer types, or if the data needs to be passed to/from native code). They also handle offsets and counts for you which can helpful.
Code generation - write code that generates the appropriate bytceode for the specialised primitive methods (either ahead of time or dynamically). This is not for the faint-hearted, but is one way to get absolutely optimal performance. You'll probably want to use a library like ASM, or alternatively pick a JVM language that can easily do the code generation for you (Clojure springs to mind).
There simply isn't. The only way to have a variable number of parameters in a method is to use the ... operator, which does not support primitives. All generics also only support primitives.
The only thing I can possibly think of would be a class like this:
class ReallyBadPrimitives {
char[] chars;
int[] ints;
float[] floats;
}
And resize the arrays as you add to them. But that's REALLY, REALLY bad as you lose basically ALL referential integrity in your system.
I wouldn't worry about garbage collection - I would solve your problems using objects and autoboxing if you have to (or better yet, avoiding this "unknown set of input parameters" and get a solid protocol down). Once you have a working prototype, see if you run into performance problems, and then make necessary adjustments. You might find the JVM can handle those objects better than you originally thought.
Try to use the ... operator:
static int sum (int ... numbers)
{
int total = 0;
for (int i = 0; i < numbers.length; i++)
total += numbers [i];
return total;
}
You can use BitSet similar to C++ Bit field.
http://docs.oracle.com/javase/1.3/docs/api/java/util/BitSet.html
You could also cast all your primitives to double then just pass in an array of double. The only trick there is that you can't use the boolean type.
Fwiw, something like sum(int... numbers) would not autobox the ints. It would create a single int[] to hold them, so there would be an object allocation; but it wouldn't be per int.
public class VarArgs {
public static void main(String[] args) {
System.out.println(variableInts(1, 2));
System.out.println(variableIntegers(1, 2, 3));
}
private static String variableInts(int... args) {
// args is an int[], and ints can't have getClass(), so this doesn't compile
// args[0].getClass();
return args.getClass().toString() + " ";
}
private static String variableIntegers(Integer... args) {
// args is an Integer[], and Integers can have getClass()
args[0].getClass();
return args.getClass().toString();
}
}
output:
class [I
class [Ljava.lang.Integer;
How is the value of an enum calculated? Does the compiler give it a static value? What kind of value is it?
The reason I ask is because I was wondering what the consequences of using enum values over a tcp (or any inter-process) connection would be. (By enum value I mean Enum.VALUE) Obviously you wouldn't be able to construct packets compatible with your program from another language unless you knew the pre-determined values of each enum. So is it possible to figure out the "real" values of each? And will two Java programs using the same enum "class" file understand each other?
This is purely theoretical, please no scoldings. Pointers are good, though.
As has been explained, don't rely on underlying implementations. Instead, design your enum to store this sort of information under your control. Imagine you have three commands to send to some embedded controller, done by writing a bit pattern to a register. You want to use enums to give you a high-level representation of the commands, but at some point you need those pesky bit patterns:
public enum EmbeddedControllerCommand {
FOO(0x001), BAR(0x010), BAZ(0x100);
private int bitPattern = 0;
EmbeddedControllerCommand(int bitPattern) {
this.bitPattern = bitPattern;
}
public int getBitPattern() {
return this.bitPattern;
}
}
Just call EmbeddedControllerCommand.FOO.getBitPattern() to get the command pattern for the FOO command.
in Java Enums do have integer reference that Java calls ordinal. For example you can do yourEnumVariable.ordinal() to get the int number of the enum variable. The numbers are assigned in a way that first in the list gets number 0, second number 1 and so on.
However in your case it sounds like you should not be concerned about what is the internal representation of enums. You should decide on what kind of protocol you will use to transfer information. After that you can think of how to transfer enum values. You'll probably have to anyway build some mapping classes for the protocol to map from Java to the protocol.
If you refer to the Enum JavaDoc you can read that the Enum.ordinal() method returns a numeric constant value which is determined by the order of the Enum declarations in the class file.
For example, consider these enum constants in alphabetical order:
public enum Fruit{
APPLE, // APPLE.ordinal() == 0
ORANGE;// ORANGE.ordinal() == 1
PEAR, // PEAR.ordinal() == 2
}
But if we add BANANA in its alphabetical position, see how the values would change, breaking any code that relies on them:
public enum Fruit{
APPLE, // APPLE.ordinal() == 0
BANANA,// BANANA.ordinal() == 1
ORANGE;// ORANGE.ordinal() == 2
PEAR, // PEAR.ordinal() == 3
}
This means that, so long as you're using the same version of the source code, you can rely on the underlying value being the same, and can use it for situations where there are no other options. I say no other options because by making your code dependent on the order of the enums, it makes the code more fragile, whereas if you aren't relying on the ordinal value you can reorder existing or insert new enum constants at will.
Now, would you accept a mild scolding for not reading the JavaDocs thoroughly before post? :)
You should not rely the pre-assinged value of enum given by Java compiler. Different language has different scheme to deal with enum. In Java, enum can be treated like a class and objects (not exactly for the same purpose) so you can create a constructor in your enum and initialize the enum to the value you want. Here is a fairly clear examples:
http://download.oracle.com/javase/tutorial/java/javaOO/enum.html
I'm looking at some Java code that are maintained by other parts of the company, incidentally some former C and C++ devs. One thing that is ubiquitous is the use of static integer constants, such as
class Engine {
private static int ENGINE_IDLE = 0;
private static int ENGINE_COLLECTING = 1;
...
}
Besides a lacking 'final' qualifier, I'm a bit bothered by this kind of code. What I would have liked to see, being trained primarily in Java from school, would be something more like
class Engine {
private enum State { Idle, Collecting };
...
}
However, the arguments fail me. Why, if at all, is the latter better than the former?
Why, if at all, is the latter better
than the former?
It is much better because it gives you type safety and is self-documenting. With integer constants, you have to look at the API doc to find out what values are valid, and nothing prevents you from using invalid values (or, perhaps worse, integer constants that are completely unrelated). With Enums, the method signature tells you directly what values are valid (IDE autocompletion will work) and it's impossible to use an invalid value.
The "integer constant enums" pattern is unfortunately very common, even in the Java Standard API (and widely copied from there) because Java did not have Enums prior to Java 5.
An excerpt from the official docs, http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html:
This pattern has many problems, such as:
Not typesafe - Since a season is just an int you can pass in any other int value where a season is required, or add two seasons together (which makes no sense).
No namespace - You must prefix constants of an int enum with a string (in this case SEASON_) to avoid collisions with other int enum types.
Brittleness - Because int enums are compile-time constants, they are compiled into clients that use them. If a new constant is added between two existing constants or the order is changed, clients must be recompiled. If they are not, they will still run, but their behavior will be undefined.
Printed values are uninformative - Because they are just ints, if you print one out all you get is a number, which tells you nothing about what it represents, or even what type it is.
And this just about covers it. A one word argument would be that enums are just more readable and informative.
One more thing is that enums, like classes. can have fields and methods. This gives you the option to encompass some additional information about each type of state in the enum itself.
Because enums provide type safety. In the first case, you can pass any integer and if you use enum you are restricted to Idle and Collecting.
FYI : http://www.javapractices.com/topic/TopicAction.do?Id=1.
By using an int to refer to a constant, you're not forcing someone to actually use that constant. So, for example, you might have a method which takes an engine state, to which someone might happy invoke with:
engine.updateState(1);
Using an enum forces the user to stick with the explanatory label, so it is more legible.
There is one situation when static constance is preferred (rather that the code is legacy with tonne of dependency) and that is when the member of that value are not/may later not be finite.
Imagine if you may later add new state like Collected. The only way to do it with enum is to edit the original code which can be problem if the modification is done when there are already a lot of code manipulating it. Other than this, I personally see no reason why enum is not used.
Just my thought.
Readabiliy - When you use enums and do State.Idle, the reader immediately knows that you are talking about an idle state. Compare this with 4 or 5.
Type Safety - When use enum, even by mistake the user cannot pass a wrong value, as compiler will force him to use one of the pre-declared values in the enum. In case of simple integers, he could even pass -3274.
Maintainability - If you wanted to add a new state Waiting, then it would be very easy to add new state by adding a constant Waiting in your enum State without casuing any confusion.
The reasons from the spec, which Lajcik quotes, are explained in more detail in Josh Bloch's Effective Java, Item 30. If you have access to that book, I'd recommend perusing it. Java Enums are full-fledged classes which is why you get compile-time type safety. You can also give them behavior, giving you better encapsulation.
The former is common in code that started pre-1.5. Actually, another common idiom was to define your constants in an interface, because they didn't have any code.
Enums also give you a great deal of flexibility. Since Enums are essentially classes, you can augment them with useful methods (such as providing an internationalized resource string corresponding to a certain value in the enumeration, converting back and forth between instances of the enum type and other representations that may be required, etc.)