I've recently discovered an interesting way to create a new instance of an object in Google Guava and Project Lombok: Hide a constructor behind a static creator method. This means that instead of doing new HashBiMap(), you do HashBiMap.create().
My question is why? What advantage do you have of hiding the constructor? To me I see absolutely no advantage of doing this, and it seems to break basic object creation principles. Since the beggining you create an object with new Object(), not some Object.createMe() method. This almost seems like creating a method for the sake of creating a method.
What do you gain from doing this?
There are a number of reasons why you might prefer a static factory method instead of a public constructor. You can read Item 1 in Effective Java, Second Edition for a longer discussion.
It allows the type of the object returned by the method to be different than the type of the class that contains the method. In fact, the type returned can depend on the parameters. For example, EnumSet.of(E) will return a different type if the emum type has very few elements vs if the enum type has many elements (Edit: in this particular case, improving performance for the common case where the enum doesn't have many elements)
It allows caching. For instance, Integer.valueOf(x) will, by default, return the same object instance if called multiple times with the same value x, if x is between -128 and 127.
It allows you to have named constructors (which can be useful if your class needs many constructors). See, for example, the methods in java.util.concurrent.Executors.
It allows you to create an API that is conceptually simple but actually very powerful. For instance, the static methods in Collections hides many types. Instead of having a Collections class with many static methods, they could have created many public classes, but that would have been harder for someone new to the language to understand or remember.
For generic types, it can limit how much typing you need to do. For example, instead of typing List<String> strings = new ArrayList<String>() in Guava you can do List<String> strings = Lists.newArrayList() (the newArrayList method is a generic method, and the type of the generic type is inferred).
For HashBiMap, the last reason is the most likely.
This is usually done because the class actually instantiated by the create() method might be different than the type upon which you are invoking the method. i.e. a factory pattern where the create() method returns a specific subclass that is appropriate given the current context. (For example, returning one instance when the currrent environment is Windows, and another when it is Linux).
Unlike constructors, static methods can have method names. Here's a recent class I wrote where this was useful:
/**
* A number range that can be min-constrained, max-constrained,
* both-constrained or unconstrained.
*/
public class Range {
private final long min;
private final long max;
private final boolean hasMin;
private final boolean hasMax;
private Range(long min, long max, boolean hasMin, boolean hasMax) {
// ... (private constructor that just assigns attributes)
}
// Static factory methods
public static Range atLeast (long min) {
return new Range(min, 0, true, false);
}
public static Range atMost (long max) {
return new Range(0, max, false, true);
}
public static Range between (long min, long max) {
return new Range(min, max, true, true);
}
public static Range unconstrained () {
return new Range (0, 0, false, false);
}
}
You couldn't do this using just constructors, as atLeast and atMost would have the exact same signature (they both take one long).
This is called a Factory method pattern. Where the factory lies within the class itself. Wikipedia describes it pretty well but here are a few snippets.
Factory methods are common in toolkits and frameworks where library code needs to create objects of types which may be subclassed by applications using the framework.
Parallel class hierarchies often require objects from one hierarchy to be able to create appropriate objects from another.
Well it would be possible for SomeClass.create() to pull an instance from a cache. new SomeClass() won't do that without some shenanigans.
It would be also be possible for create() to return any number of implementations of SomeClass. Basically, a Factory type of dealio.
Although not applicable to this particular code example, the practice of hiding the constructor behind a static method is Singleton Pattern. This is used when you want to ensure that a single instance of the class is created and used throughout.
There are many reasons to use this factory method pattern, but one major reason Guava uses it is that it lets you avoid using type parameters twice when creating a new instance. Compare:
HashBiMap<Foo, Bar> bimap = new HashBiMap<Foo, Bar>();
HashBiMap<Foo, Bar> bimap = HashBiMap.create();
Guava also makes good use of the fact that factory methods can have useful names, unlike constructors. Consider ImmutableList.of, ImmutableList.copyOf, Lists.newArrayListWithExpectedSize, etc.
It also takes advantage of the fact that factory methods don't necessarily have to create a new object. For instance, ImmutableList.copyOf, when given an argument that is itself an ImmutableList, will just return that argument rather than doing any actual copying.
Finally, ImmutableList's factory methods return (non-public) subclasses of ImmutableList such as EmptyImmutableList, SingletonImmutableList and RegularImmutableList depending on the arguments.
None of these things are possible with constructors.
i got very interesting reason to hide constructor check it and please let me know if there is any other alternative to achieve this
enter code here
Class A
{
String val;
protected A( )
{
}
protected A(String val)
{
this.val=val;
}
protected void setVal( String val)
{
this.val=val;
}
public String getVal()
{
return val;
}
}
class B extends A
{
B()
{
super();
}
public val setVal(String val)
{
super.val=val;
}
}
class C extends A
{
C(String val)
{
super(val);
}
}
Some main reasons
Primarily it gives you the power to instantiate a different (sub) class
Possibility to return null
It enables you to return an already existing object
Related
I'm fairly new to programming and we do have an exercise, we have to use the Consumer interface, we have a generic class (genClass) that has a Consumer<T> attribute (conAtt). In another class we have to use the accept method of Consumer, but somehow it doesn't work. I have already read through the Java API of the Consumer interface, but it didn't help.
The error message says:
The method accept(capture#4-of ?) in the type Consumer<capture#4-of ?> is not applicable for the arguments (capture#5-of ?)
I know it says not applicable, but why not?
public abstract class GenClass<T> {
protected Consumer<T> conAtt;
public abstract T getData();
}
class Otherclass{
private List<GenClass<?>> helparray= new ArrayList<>();
private void testmethod() {
Iterator<GenClass<?>> hilfe = helparray.iterator();
while (hilfe.hasNext()) {
GenClass<?> help = hilfe.next();
help.conAtt.accept(help.getData());//here is the problem
}
}
}
public class thirdclass extends GenClass<Character> {
#Override
public Character getData() {
return 't';//t is just an example
}
}
This is not really a question about how the Consumer - or other interfaces - in Java work, but about Generics.
Generics aim to simplify the way of writing code and avoid code repetitions. E.g. you need to do a similar task, but for different types you can write it once by using Generics instead of writing it over and over again, just with concrete types being replaced.
For example one day you have the need to keep track of a list of Strings. As easy as that, your going ahead and implementing a solution for that, whereby the first implementation can look like the following (note: a very simplified example, but it'll show the purpose):
public class CustomListString {
private String[] elements = new String[10];
public void add(String newElement) {
int nextFreeIndex = findNextFreeIndex();
elements[nextFreeIndex] = newElement;
}
public String get(int index) {
return elements[index];
}
}
So you can use the above implementation of the List in your code like the following:
public static void main(String[] args) {
CustomListString listOfStrings = new CustomListString();
listOfStrings.add("A");
listOfStrings.add("B");
}
Simple, specific and sufficient!
But the other day, you also have the requirement to keep track of a list of Integers. What to do now?
A way to solve this is to just repeat your previous approach and to implement another CustomList only for the Integers now. Where the corresponding implementation would look like this (the implementation of CustomListString has been copied and all occurrences of String have been replaced by Integer):
public class CustomListInteger {
private Integer[] elements = new Integer[10];
public void add(Integer newElement) {
int nextFreeIndex = findNextFreeIndex();
elements[nextFreeIndex] = newElement;
}
public Integer get(int index) {
return elements[index];
}
}
As you can imagine now already, this is not flexible and can be very cumbersome in the future. This approach will require a new implementation of each type you want to store in the future. So you might end up to also create implementations like CustomListDouble, CustomListCharacter, ... and so on, in which only the type of the elements within the array change - nothing else which would be of importance!
This will additionally lead to the situation, that you'll duplicate a lot of similar code (like findNextFreeIndex() method would have been) and in case of a bugfix need to adjust it in a lot of places instead of in only one.
To solve this issue and remain the type safety in the CustomList.get method Generics have been introduced to Java!
With the Generics approach you'll be able to create a single implementation of the CustomList to store all of your data types without unnecessarily duplicating any shared, basic code and remain the type safety!
public class CustomList<T> {
private Object[] elements = new Object[10]; // Java doesn't supprort easily support generic arrays, so using Object
// here. But the compiler ensures only elements of the generic type T
// will end up here
public void add(T newElement) {
int nextFreeIndex = findNextFreeIndex();
elements[nextFreeIndex] = newElement;
}
#SuppressWarnings("unchecked")
public T get(int index) {
return (T) elements[index];
}
}
Using the new list following the Generics approach we can use it like this now:
public static void main(String[] args) {
CustomList<String> genericList = new CustomList<>();
genericList.add("Hello World");
genericList.add(5); // Compile error! Integer and String types cannot be mixed in
// a single instance of the list anymore => Nice, prevents errors!
genericList.get(0).substring(6); // No compile error, also the compiler knows Strings
// are contained in the list
}
The generic CustomList can now also be reused for any other type and still provide type safety.
What does it mean for your implementation
You can see how we specified the generic type in the CustomList class as T - this is similar like you specified it with ? (probably you'll also want to replace it with T, since you'll run into other issues later when working with the Consumer). But when we used the implementation in our other classes, it wouldn't have been possible to specify it as CustomList<T> or CustomList<?> anymore. We needed to decide and specifiy which exact type of elements the list should contain. This has been the String class, so we specified it as CustomList<String>.
Note: ? is a generic wildcard and means something like "I don't know the real type of the classes now and I'll also don't know it in the future". That's why it'll be hard for you working with the concrete types later in the Consumer. You'll be not able to call any conrete methods on your objects therein. Therefore ? should be avoided as a generic type argument and something like T should be used instead. T means something like "I don't know the real type of the classes now, but I'll do later, as soon as you tell me". Therfore you'll be able to call concrete methods on the objects later in the Consumer, what will simplify your work there a lot.
For your code this means, wherever you want to use your implementation of GenClass<T> you need to specify with which exact kind of elements the class is going to work with. In case of String it is GenClass<String> in case of Character GenClass<Character>.
So the place you'll need to replace the occurrences of GenClass<?> is wherever you refer to it in Otherclass and Otherclass.testmethod.
The way you used the Consumer is fine
In java an AtomicMarkableReference can be used to update atomically an object reference along with a mark bit.
The javadoc states:
Implementation note: This implementation maintains markable references by creating internal objects representing "boxed" [reference, boolean] pairs.
This is true according to what can be seen in the java 8 source code of the class:
package java.util.concurrent.atomic;
public class AtomicMarkableReference<V> {
private static class Pair<T> {
final T reference;
final boolean mark;
private Pair(T reference, boolean mark) {
this.reference = reference;
this.mark = mark;
}
static <T> Pair<T> of(T reference, boolean mark) {
return new Pair<T>(reference, mark);
}
}
private volatile Pair<V> pair;
public AtomicMarkableReference(V initialRef, boolean initialMark) {
pair = Pair.of(initialRef, initialMark);
}
// [...] class methods
}
Is there a reason behind the design of the get method of the class?
public V get(boolean[] markHolder) {
Pair<V> pair = this.pair;
markHolder[0] = pair.mark;
return pair.reference;
}
What is the point of using such boolean array (instead of returning the pair of values)? Is a concurrency-driven choice? Or perhaps legacy code?
This is because Java has no Pair<L, R> class and probably will not, even despite of the fact that standard library has at least three classes which have private static class Pair. Adding Pair class were discussed by OpenJDK developers more than once and proposal was always rejected. This mail is a very good explanation why pair shouldn't be presented as standard class (also, the whole mail thread is very useful):
The problem is that classes like Pair simply go that much further to indulge
the desire to never have to create any actual types of our own. When we're
forced to create our own types, we begin to model our data more
appropriately, which I believe leads us to create good abstractions at
broader levels of granularity as well.
As long as AtomicMarkableReference doesn't expose its Pair class and in Java you can't change value of passed reference (in the way that such change will be observable by caller), the only way to return both reference and bit flag is to return one of them from method and set second into passed as argument array. So it's not about concurrency, neither about legacy, it's about language design decision.
I have been working to upgrade my Java code baseline so that it follows good security practices and have run into an issue related to generics. Say you have the following:
public class SomeClass<T>
{
private T value;
public T getValue()
{
return value;
}
public void setValue(T value)
{
this.value = value;
}
}
I have not found a good answer on how to edit these methods so that value does not leak like it does in this example class for a generic object that does not implement Clonable and in some cases has no default constructor.
As I understand it, you want to make sure that nothing outside SomeClass can mutate the object value.
In C++, you could returns a const reference (avoid copying altogether), but Java does not have that. So let's look at copying...
First, know that some objects cannot be copied. For example, stream, gui elements, etc. Thus, trying to copy all objects is a hopeless endeavor from the start.
But what about objects that are copiable?
In Java, you cannot call the copy constructor (or any other constructor) of a generic (Calling constructor of a generic type).
There is the Cloneable interface, but that is really nothing more than a promise that clone works; it does not actually expose clone publically. Thus, for generics, you have to use reflection, as shown here.
Unfortunately, there is no good solution. The only viable one (except for changing the purpose or semantics of your class) is to use the clone method as shown in the link above, and realize that some objects cannot be copied.
Ultimately, the best thing to do is find a solution that does not require this. Make a (non-generic) read-only wrapper class that exposes the non-mutating methods. Or stipulate in documentation that mutating methods must not be called.
I can see three approaches:
Make copies. This of course would only work with types can can be copied (and that you know how to copy).
Only support immutable types.
Remove getValue(). Instead, provide methods that operate directly on this.value without exposing it outside the class. In this approach, setValue() can still be problematic (you need to make sure that the caller does not hold on to the object reference after calling setValue()).
If T can be arbitrary type that you have no control over, then options 1 and 2 won't be suitable.
I believe that i undestand you ... If you want to restrict a generic type you should use extends keyword that in generic type is not equals to general class. If you use only the class how implements Clonable are able to instantiate this class. One example:
public class Stack {
public static void main(String[] args) {
SomeClass<Animal> sc = new SomeClass<>(); //This generate an error because doesnt implements Clonable interface
SomeClass<Person> sc1 = new SomeClass<>();
}
}
class SomeClass<T extends Comparable> //Note that extends means implements or the common extends
{
private T value;
public T getValue()
{
return value;
}
public void setValue(T value)
{
this.value = value;
}
}
class Person implements Comparable<Person>{
#Override
public int compareTo(Person p){
return 0;
}
}
class Animal {
}
I wish i helped you.
:)
An object whose state is encapsulated in a mutable object should generally never expose to the outside world any reference to that object, and should avoid giving the outside world a reference to any mutable object (even a copy) which claims to encapsulate its state. The problem is that given code:
Foo foo = myEntity1.getFoo();
foo.bar = 23;
myEntity2.setFoo(foo);
foo.bar = 47;
myEntity3.setFoo(foo);
there is no clear indication whether or how the change to foo.bar would affect the various entities. If the code had instead been:
Foo foo = myEntity1.getFoo();
foo = foo.withBar(23); // makes a new instance which is like foo, but where bar==23
myEntity2.setFoo(foo);
foo = foo.withBar(47); // makes a new instance which is like foo, but where bar==47
myEntity3.setFoo(foo);
it would be very clear that the bar property of myEntity1's foo will be unaffected, that of myEntity2 will be 23, and that of myEntity3 will be 47. If foo is a mutable class, the pattern should be:
Foo foo = new Foo();
myEntity1.writeTo(foo); // Copy properties from myEntity1 to the supplied instance
foo.bar = 23;
myEntity2.readFrom(foo); // Copy properties from the supplied instance to myEntity2
foo.bar = 47;
myEntity2.readFrom(foo); // Copy properties from the supplied instance to myEntity3
Here, myEntity1 isn't giving the caller an object, but is instead copying data to an object supplied by the caller. Consequently, it's much clearer that the caller shouldn't expect the writes to foo.bar to affect the entities directly, but merely change what will be written in subsequent readFrom calls.
In a Java class a method can be defined to be final, to mark that this method may not be overridden:
public class Thingy {
public Thingy() { ... }
public int operationA() {...}
/** this method does #return That and is final. */
public final int getThat() { ...}
}
That's clear, and it may be of some use to protect against accidental overriding, or maybe performance — but that's not my question.
My question is: From an OOP point of view I understood that, by defining a method final the class designer promises this method will always work as described, or implied. But often this may be outside the influence of the class author, if what the method is doing is more complicated then just delivering a property.
The syntactic constraint is clear to me, but what is the implication in the OOP sense? Is final used correctly in this sense by most class authors?
What kind of "contract" does a final method promise?
As mentioned, final is used with a Java method to mark that the method can't be overridden (for object scope) or hidden (for static). This allows the original developer to create functionality that cannot be changed by subclasses, and that is all the guarantee it provides.
This means that if the method relies on other customizable components like non-public fields/methods the functionality of the final method may still be customizable. This is good though as (with polymorphism) it allows for partial customization.
There are a number of reasons to prevent something from being customizable, including:
Performance -- Some compilers can analyse and optimise the operation, especially the one without side-effects.
Obtain encapsulated data -- look at immutable Objects where their attributes are set at the construction time and should never be changed. Or a calculated value derived from those attributes. A good example is the Java String class.
Reliability and Contract -- Objects are composed of primitives (int, char, double, etc.) and/or other Objects. Not all operations applicable to those components should be applicable or even logical when they are used in the bigger Object. Methods with the final modifier can be used to ensure that. The Counter class is a good example.
public class Counter {
private int counter = 0;
public final int count() {
return counter++;
}
public final int reset() {
return (counter = 0);
}
}
If the public final int count() method is not final, we can do something like this:
Counter c = new Counter() {
public int count() {
super.count();
return super.count();
}
}
c.count(); // now count 2
Or something like this:
Counter c = new Counter() {
public int count() {
int lastCount = 0;
for (int i = super.count(); --i >= 0; ) {
lastCount = super.count();
}
return lastCount;
}
}
c.count(); // Now double count
What kind of "contract" does a final method promise?
Look at it the other way, any non final method makes the implicit guarantee that you can override it with your own implementation and the class will still work as expected. When you can't guarantee that your class supports overwriting a method you should make it final.
First of all, you can mark non-abstract classes final as well as fields and methods. This way whole class can't be subclassed. So, behavior of class will be fixed.
I agree that marking methods final don't guarantee that their behavior will be the same in subclasses if these methods are calling non-final methods. If behavior is indeed need to be fixed, this has to be achieved by convention and careful design. And don't forget to notion this in javadoc!(java documentation)
Last but not the least, final keyword has very important role in Java Memory Model (JMM). It's guaranteed by JMM that to achieve visibility of final fields you don't need proper synchronization. E.g.:
class A implements Runnable {
final String caption = "Some caption";
void run() {
// no need to synchronize here to see proper value of final field..
System.out.println(caption);
}
}
I'm not sure you can make any assertions about the use of "final" and how that impacts the overall design contract of the software. You are guaranteed that no developer can override this method and void its contract that way. But on the other hand, the final method may rely on class or instance variables whose values are set by subclasses, and can call other class methods that are overridden. So final is at most a very weak guarantee.
No, it's not outside the influence of the class author. You can't override it in your derived class, therefore it will do what the base class author intended.
http://download.oracle.com/javase/tutorial/java/IandI/final.html
Worth noting is the part where it suggests that methods called from constructors should be final.
i am trying to create a abstract array method that specify's that this abstract object of an array can only hold 3 items.
Now i have tried doing something like this public abstract BaseAdapter[3] adapters(); but it complains with an error that it cant be done this way.
is their another way or do i need to just do public abstract BaseAdapter[] adapters();?
That will work fine but the sub class can still pass an array larger than 3 items
You could solve it like this:
Create an abstract helper method (which you can override) named createAdapters() with return type BaseAdapter[]
protected abstract BaseAdapter[] createAdapters();
In your super-class you have a final method adapters that does the following:
public final BaseAdapter[] adapters() {
BaseAdapter[] adapters = createAdapters();
if (adapters.length != 3)
throw new Exception("Error: Please return 3 adapters.");
return adapters;
}
Another alternative would be to create a simple class called BaseAdapterTriple (perhaps with a more descriptive name) containing the three BaseAdapters, and use that as return value.
As far as I'm aware there is no way to place restrictions like that on objects in a method signature. Either use exceptions in implementing methods, or use custom classes.
You seem to misunderstand the meaning of the abstract modifier in Java.
abstract applies to classes and methods, not to fields / variables, so what you are trying cannot work.
Please describe what you want to accomplish, then we can help :-).
See e.g. http://download.oracle.com/javase/tutorial/java/IandI/abstract.html for an explanation of abstract.
No, you can't do this neither with arrays nor lists. You can throw an exception if number exceeds 3 and document this behavior.
If you want an adapters() method which can only return 3 BaseAdapter at most and having subclasses to implement the "return" themselves while respecting the 3max contract, you should do the verification in your adapters() method, and invoke an abstract method.
For example :
abstract class YourAbstractClass{
public BaseAdapter[] adapters(){
BaseAdapter[] adapters = internalAdapters();
if(adapters.length > 3){
throw new IllegalStateException();
}
return adapters;
}
protected abstract BaseAdapter[] internalAdapters();
}
aioobe's answer is a good approach to take, but I'd also suggest something a little bit different:
If you are requiring a method to return an array of a certain size, you might want to question why an array is the appropriate return type for this method in the first place, rather than using a simple POJO which can easily encapsulate the idea of "3 BaseAdapters", i.e.:
public class ThreeAdapters {
BaseAdapter getAdapter1() { ...}
BaseAdapter getAdapter2() { ...}
BaseAdapter getAdapter3() { ...}
}
It's a lot clearer to everyone involved if you encapsulate the idea of "return 3 adapters" into it's own class so that this can be used as the return type (of course, you may find a more appropriate name for the class).
In Java, the size of an array is not part of its type. Or to put it another way, all array types with a given base type are the same. Furthermore, you cannot a method signature that places restrictions on the size of an array typed parameter or result.
This means that you are left with the coding the method to test (in your case) the length of the array it is about to return. This is probably not going to help you much, since I assume that you are trying leverage static typing to enforce the "tripleness" of your arrays. From this perspective #matt b's answer is on the money, though you could make do it in a way that still gives you arrays (of length 3):
public class AdapterTriple {
private Adapter[] adapters;
/**
* This constructor may throw an exception
*/
public AdapterTriple(Adapter[] adapters) {
if (adapters.length != 3) {
throw new IllegalArgumentException("array length is wrong");
}
this.adapters = adapters;
}
/**
* This constructor won't throw an exception (apart from Errors)
*/
public AdapterTriple(Adapter adapter1, Adapter adapter2, Adapter adapter3) {
this.adapters = adapters = new Adapters[] {
adapter1, adapter2, adapter3};
}
/**
* #return an array of 3 adapters.
*/
public Adapter[] {
return adapters;
}
}
In summary, you cannot enforce array size constraints statically in Java. You have to do it dynamically, but you can take steps to make runtime errors unlikely.