Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Would it be overhead to always return a copy of collection/object field?
Clearly, yes it would be a overhead ... compared with returning a reference or a shallow copy.
But that's not really the point. The real point is whether the overhead is warranted / necessary, and whether it can be avoided by using some other data structure / design / technique. The answer to those questions depends on the context.
Here are some illustrations:
If a target object getter returns an immutable object, a copy is unnecessary. Example, any getter that returns a String.
If a target object getter returns an object that is not part of the target object abstraction, a copy is undesirable. Example list.get(int), Iterator.next().
If a target object getter returns a mutable object (or array) AND the returned object is part of the object's internal state AND the target doesn't necessarily trust the caller, then the getter should either copy it or wrap it ... or there may be a security problem.
The same may apply in non-security-related contexts; e.g. ArrayList.toArray(...) copies the list into an separate array rather than returning the list's backing array. (Similar for getChars() for a String, StringBuffer, etc.) This is all about maintaining the abstraction boundary so that on class won't "break" another one.
If a target object getter returns a mutable object (or array) AND the returned object is part of the object's internal state BUT the target object's API / abstraction boundary is designed to be "porous" (e.g. for performance reasons), then copying may be self defeating.
Of these, 3 is the only case where cloning is strictly mandatory. In 2, 4 and 5 you could argue that it is a matter of how you design the public (or internal) APIs for the classes, libraries, applications. And often there are many viable choices.
It is overhead for sure but there are already some framework classes which do that. It is also described in the book Effective Java.
Remember:
"Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, limit its mutability as much as possible."
When you want to create immutable classes than you can use a framework like that: http://immutables.github.io
For examples check this Oracle documentation
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
The builder pattern is one of the most popular creation patterns, and it has numerous benefits. I specifically want to understand if immutability of the model object itself is one of the key benefits. All the while I thought it was, but I could not find any backing documentation on the same. Consider this scenario, you are creating an object from a network call (from json let's say). We create model objects and it has a Builder inline. This is what everybody does. The members of the model are also private. Since this is a network object, the members won't have setters. My doubts are
With builder securing object creation, do we need to make members private.
Can we instead keep them public final and eliminate need for getter()
In general (irrespective of the above two points), shouldn't all non-settable members be final? I don't see many people making members final, why is it so?
Is this a good approach or not?
I'm really having my pain with the example you chose. Parsing JSON into objects is really something you can delegate to JSON-B / Jackson / insert JSON library here nowadays. But I get it that we're on a theoretical level here.
Wikipedia just says: The intent of the Builder design pattern is to separate the construction of a complex object from its representation.
From the theory, the builder pattern neither forces immutability nor is it any aspect of it.
With builder securing object creation, do we need to make members
private.
You don't need to do anything. But there is one simple stylistic rule: You either access members by getters and setters or by making them public. But not both.
Can we instead keep them public final and eliminate need for getter()
Final would imply immutability - if that's what you want to achieve, you can do so.
In general (irrespective of the above two points), shouldn't all
non-settable members be final? I don't see many people making members
final, why is it so? Is this a good approach or not?
You only make members final if you want them to be immutable or if they are constants. Otherwise it makes no sense. With your example, I can only think of constant values? However, you cannot make members final without setting their value. You either need to set them in the constructor or initialise them to null. But having final null values most likely doesn't serve any purpose.
The better approach for such values would be really just not to define a getter or setter and making it private. But then you again have just some useless null values laying in your class.
To be frank, this whole discussion about getters/setters or public is opening Pandora's box. I have had too many discussions about this by now, and it just doesn't matter which way you do it. In the end both serve the same purpose: setting and retrieving values.
Regarding final values: I don't have to use immutability often to be frank, in my area of development I can't really think of any case I've used it so far. The only thing I use it for is to mark constant values which I don't want to be changed by anything.
In the end, this whole discussion about design patterns is tedious. A builder is just a helping structure. You have to find your way on how to use it for your use case and in your company. Just remind you of the fact that it's whole purpose is to make the creation of complex objects more accessible.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
First I wish to state that I'm aware of the javadoc of java.lang.Object.hashCode() and thus there's no need to mention it again.
What I'm asking is: Why isn't java.lang.Object.hashCode() moved into a seperate interface named (probably) Hashable? Like `java.lang.Comparator'?
To me, hashCode() is only used in hash-dependent data structures like HashMap or HashTable, which a) are not used in every application b) are often used with very few types of keys like String or Integer and not with a InputStream (or something like it).
I know that I do not have to implement hashCode() for every class of mine, however, isn't adding a method to a class at the cost of performance to some extent? Especially for java.lang.Object - the superclass of every class in Java.
Even if special optimization is done within the JVM so that the lost of performance can be ignored, I still think that it's unwise to provide every Object with a behavior that is not frequently implemented at all. According to the Interface Segregation Principle:
No client should be forced to depend on methods it does not use.
I did some searches in the web and the only related page I could find is this.
The first answer expressed (partly) the same idea as mine, and some others tried to answer the question, saying mainly that "hashCode() for every Object enables storage of object of any type in HashMap", which I take as not satisfactory.
I here propose my own solution, which satisfies both the Interface Segregation Principle and the ability to store anything in a HashMap without adding much complexity the whole system:
Remove hashCode() from java.lang.Object.
Let there be an interface Hashable, containing hashCode() with the same contract as the former java.lang.Object.hashCode().
Let there be an interface HashProvider with a type parameter T containing provideHashCode(T t) to provide a hash code for an object. (Think of Comparator<T>).
Let there be an implementation of HashProvider<Object> called DefaultHashProvider which generates the hash code for any Object using the current implementation of Object.hashCode(). (As for Java 8, Object.hashCode() is a native method, I expect DefaultHashProvider.provideHashCode() to return the same thing for any Object)
Modify constructors of HashMap and HashTable so that everything can be stored in them by:
Using the provideHashCode() if a HashProvider is specified.
Using the hashCode() if its underlying elements implement Hashable.
Using DefaultHashProvider otherwise.
I believe that this is possible in practice because it's just a variation of the system of Comparable, Comparator and TreeMap.
And let my repeat my question:
Considering that the Java development team should not be unable to come up with a solution similar to mine, is there any good reason for not doing so? Are there some advanced considerations that I'm currently unaware of? I have the following hypotheses, does any of them approach the correct answer?
Some language features required by this solution, like generic types, are available only well after the very beginning of Java - since 1.5. However, I would argue that Comparator, Comparable along with TreeMap exist since 1.2, can't the technique used to write them be adapted to HashMap?
hashCode() is used somewhere within the JVM and therefore it requires every Object to have a hash code. However this can also be available using DefaultHashProvider.provideHashCode() (or its native implementation) for non-hashables.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Thinking about this question, I don't think it would be bad since object references only take up 4 bytes of memory (in a 32-bit JVM), but intuitively I feel like I'm doing something wrong when I have many (+100) references to the same object. This usually happens when I create a certain class +100 times and each need to hold the reference.
I know I can re-design my code in most cases to avoid this, but sometimes its much easier to just keep the reference within each object.
Anyway, is it bad to have many references to the same object?
Having many references to the same object is unavoidable, but has no dissadvantage IMHO.
Every Class has a reference to it from every instance of that class. Each class loader has a reference from every class. The empty String is often the most referenced object with tens of thousands of references being common.
I know I can re-design my code in most cases to avoid this, but sometimes its much easier to just keep the reference within each object.
I suggest you do what you believe is simplest and clearest and this will be easiest to maintain.
Thinking about this question, I don't think it would be bad since object references only take up 4 bytes of memory (in a 32-bit JVM), but intuitively I feel like I'm doing something wrong when I have many (+100) references to the same object.
From a performance/resource utilization standpoint, references are waaaaaaaaaaaaaaaay more efficient than creating and destroying objects. Lots of ittybitty objects can fragment the heap and tax the memory manager/garbage collector. This is why it's usually worth the effort to make immutable objects singletons. Construction of even small objects in Java is more expensive than using references.
Most programs won't notice any significant difference, but some will.
This usually happens when I create a certain class +100 times and each need to hold the reference.
If every instance of a class references that object, use a static rather than instance variable to store the reference. You can use a static initializer to allocate it, or create a factory method to instantiate objects of the class and have the factory method allocate the referenced object the first time it is invoked.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
This is my understanding about stateless objects:Any object created from class that doesn't have class variables is a stateless object.
My question is when should we write stateless classes. Is it a good habit to have stateless objects.
Stateless objects are useful if you need to "pass functionality as a parameter". Since functions are no Objects in java, it's a practical way to pass the an object with the function as parameter.
For example Comparators can be used to sort, if a class does not implement Comparable or if you need to support sorting with different definitions of the "<"-relation. (e.g. accending / descending order; sorting by different properties ...)
A factory (see http://www.oodesign.com/factory-pattern.html) may be a stateless object. All functions of the factory may create objects and all parameters necessary to create
them can be given as parameters of the functions of the factory.
Generally, if what you have is stateless (has no instance variables, only class variables), it has no reason to ever be instantiated and shouldn't be an Object (though implementing it as a class can be useful to group related functionality together and to manage access to the static class variables).
The one case where a stateless object is justified, in my opinion, is when it's a trivial implementation of an interface. For example, an immutable Collection (eg an EmptyCollection) may want to be an object so it can be passed around and manipulated like other Collection objects, but can be implemented as stateless since it's immutable and its state can never be changed.
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 9 years ago.
Improve this question
Yesterday I have attended interview in one Leading IT Service company. Technical interview was good, no issues, then I have moved to another set of round about Management, Design and Process. I have answered everything except the below question.
Question asked by interviewer:
Let say you are developing a class, which I am going to consume in my
class by extending that, what are the key points you keep in
mind? Ex, Class A, which has a method called "method A" returns a Collection,
let say "list". What are the precautions you will take?
My Answer: The following points I will consider, such as:
Class and method need to be public
Method 1 returns a list, then this needs to be generics. So we can avoid class cast exception
If this class will be accessed in a multi-threaded environment, the method needs to be synchronized.
But the interviewer wasn't convinced by my points. He was expecting a different answer from me but I am not able to get his thought process, what he was excepting.
So please provide your suggestions.
I would want you holding to design principles of Single Reaponsibility, Open/Close, and Dependency Injection. Keep it stateless, simple, and testable. Make sure it can be extended without needing to change.
But then, I wasn't interviewing you.
A few more points which haven't been mentioned yet would be:
Decent documentation for your class so that one doesn't have to dig too deep into your code to understand what functionality you offer and what are the gotchas.
Try extending your own class before handing it out to someone else. This way, you personally can feel the pain if you class is not well designed and thereby can improve it.
If you are returning a list or any collection, one important question you need to ask is, "can the caller modify the returned collection"? Or "is this returned list a direct representation of the internal state of your class?". In that case, you might want to return a copy to avoid callers messing up your internal state i.e. maintain proper encapsulation.
Plan about the visibility of methods. Draw an explicit line between public, protected, package private and private methods. Ensure that you don't expose any more than you actually want to. Removing features is hard. If something is missing from your well designed API, you can add it later. But you expose a slew of useless public methods, you really can't upgrade your API without deprecating methods since you never know who else is using it.
If you are returning a collection, the first thing you should think about is should I protect myself from the caller changing my internal state e.g.
List list = myObject.getList();
list.retainAll(list2);
Now I have all the elements in common between list1 and list2 The problem is that myObject may not expect you to destroy the contents of the list it returned.
Two common ways to fix this are to take a defensive copy or to wrap the collection with a Collections.unmodifiableXxxx() For extra paranoia, you might do both.
The way I prefer to get around this is to avoid returning the collection at all. You can return a count and a method to get the n-th value or for a Map return the keys and provide a getter, or you can allow a visitor to each element. This way you don't expose your collection or need a copy.
Question is very generic but i want to add few points:
Except the method which you want to expose make other methods and variable private. Whole point is keep visibility to minimum.
Where ever possible make it immutable, this will reduce overhead in mutithreaded environment.
You might want to evaluate if serializability is to be supported or not. If not then dont provide default constructor. And if serializable then do evaluate serialized proxy pattern.