How to use generics with interfaces - java

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

Related

Java: Create a Generic Method out of multiple methods

I came across a piece of code where two methods have very similar functionalities, return the same type, but are different.
private Set<String> extractDeviceInfo(List<Device> devices){
Set<String> sets= new HashSet<>();
for(Device item:items){
sets.add(item.getDeviceName());
}
return sets;
}
private Set<String> extractDeviceInfoFromCustomer(List<Customer> customers){
Set<String> sets= new HashSet<>();
for (Customer c : customers) {
sets.add(c.getDeviceName());
}
return sets;
}
As you can see from the code above, both methods are returning the same Set and retrieving the same data.
I'm trying to attempt to create a generic method out of it and did some research but couldn't find anything that could solve this issue.
If I understand this correctly, using generics, I can define generic parameters in the method and then pass parameters as well as the class type when calling the method. However I am not sure what to do after wards.
For example, the method getDeviceName() how can I call it out of a generic class as the compiler doesn't know whether the generic class has that method or not.
I will really appreciate if someone could tell me whether this is possible and how to achieve the desired result.
Thanks
UPDATE: Creating an interface and then having implementation looks like a good solution but I feel like it's overdoing when it comes to refactoring a couple of methods to avoid boiler plate.
I've noticed that Generic classes can be passed as a parameter and the have methods like getMethod() etc.
I was wondering if it was possible to create a generic method where you pass the class as well as the method name and then the method resolves that at runtime
eg.
private <T> Set<String> genericMethod(Class<T> clazz, String methodName ){
clazz.resolveMethod(methodName);
}
So basically, I could do this when calling the method:
genericMethod(Customer.class,"gedDeviceInfo");
I believe there's one language where this was achievable but not sure if you can do it in Java, although, a few years back I remember reading about resolving string into java code so they get compiled at runtime.
Both Device and Customer should implement the same interface where the method getDeviceName is defined:
interface Marker {
String getDeviceName();
}
class Device implements Marker { ... }
class Customer implements Marker { ... }
I named it Marker, but it's up to you to name it reasonably. Then, the method might look like:
private Set<String> extractDeviceInfo(List<? extends Marker> markers) {
return markers.stream().map(Marker::getDeviceName).collect(Collectors.toSet());
}
It allows the next type variations:
extractDeviceInfo(new ArrayList<Device>());
extractDeviceInfo(new ArrayList<Customer>());
extractDeviceInfo(new ArrayList<Marker>());
99% of the time Andrew answer is the solution. But, another approach is to define the function in parameter.
This can be useful for some reporting or if you need to be able to extract values from an instance in multiple ways using the same method.
public static <T, U> Set<U> extractInfo(List<T> data, Function<T, U> function){
return data.stream().map(function).collect(Collectors.toSet());
}
Example :
public class Dummy{
private String a;
private long b;
public Dummy(String a, long b){ this.a = a; this.b = b; }
public String getA(){return a; }
public long getB(){return b; }
}
List<Dummy> list = new ArrayList<>();
list.add(new Dummy("A1", 1));
list.add(new Dummy("A2", 2));
list.add(new Dummy("A3", 3));
Set<String> setA = extractInfo(list, Dummy::getA); // A1, A2, A3
Set<Long> setB = extractInfo(list, Dummy::getB); // 1, 2, 3
using reflection in java will take a performance hit. in your case, it's probably not worth it.
There is nothing wrong with your original code, if there are less than 3 places using it, DO NOT refactor. If there is more than 3 places and expecting more coming, you can refactor using #andrew's method.
you should not refactor code just for the sake of refactoring in my opinion.

How do I perform an action on each element of a List and return the result (without affecting the original of course)?

How do I write a static method in Java that will take a List, perform an action on each element, and return the result (without affecting the original of course)?
For example, if I want to add 2 to each element what goes in the ... here? The concrete return type must be the same, e.g. if my List is a LinkedList with values 1,2,3 I should get back a LinkedList with values 3,4,5. Similarly for ArrayList, Vector, Stack etc, which are all Lists.
I can see how to do this using multiple if (lst instanceof LinkedList) ... etc... any better way?
import java.util.List;
public class ListAdd {
static List<Integer> add2 (List<Integer> lst) {
...
return result;
}
}
There are already many answers, but I'd like to show you a different way to think of this problem.
The operation you want to perform is known as map in the world of functional programming. It is something we do really all the time in functional languages.
Let M<A> be some kind of container (in your case, M would be List, and A would be Integer; however, the container can be lots of other things). Suppose you have a function that transforms As into Bs, that is, f: A -> B. Let's write this function as of type F<A, B>, to use a notation closer to Java. Note that you can have A = B, as in the example you give (in which A = B = Integer).
Then, the operation map is defined as follows:
M<B> map(M<A>, F<A, B>)
That is, the operation will return a M<B>, presumably by applying F<A, B> to each A in M<A>.
In practice...
There's a brilliant library developed by Google, called Guava, which brings lot's of functional idioms to Java.
In Guava, the map operation is called transform, and it can operate on any Iterable. It has also more specific implementations that work directly on lists, sets, etc.
Using Guava, the code you want to write would look like this:
static List<Integer> add2(List<Integer> ns) {
return Lists.transform(ns, new Function<Integer, Integer>() {
#Override Integer apply(Integer n) { return n + 2; }
}
}
Simple as that.
This code won't touch the original list, it will simply provide a new list that calculates its values as needed (that is, the values of the newly created list won't be calculated unless needed -- it's called a lazy operation).
As a final consideration, it is not possible for you to be absolutely sure that you will be able to return exactly the same implementation of List. And as many others pointed out, unless there's a very specific reason for this, you shouldn't really care. That's why List is an interface, you don't care about the implementation.
Fundamentally, the List interface doesn't make any guarantees that you'll have a way to duplicate it.
You may have some luck with various techniques:
Using clone() on the passed in List, although it may throw, or (since it is protected in Object) simply not be accessible
Use reflection to look for a public no-argument constructor on the passed-in List
Try to serialize and deserialize it in order to perform a "deep clone"
Create some sort of factory and build in knowledge of how to duplicate each different kind of List your code may encounter (What if it's a wrapper created by unmodifiableList(), or some oddball custom implementation backed by a RandomAccessFile?)
If all else fails, either throw, or return an ArrayList or a Vector for lack of better options
You could use reflection to look for a public zero-arg constructor on the result of lst.getClass() and then invoke() it to obtain the List into which you'll place your results. The Java Collections Framework recommends that any derivative of Collection offer a zero-arg constructor. That way, your results we be of the same runtime class as the argument.
Here is a variant which does neither copies nor modifies the original list. Instead, it wraps the original list by another object.
public List<Integer> add2(final List<Integer> lst) {
return new AbstractList<Integer>() {
public int size() {
return lst.size();
}
public Integer get(int index) {
return 2 + lst.get(index);
}
};
}
The returned list is not modifiable, but will change whenever the original list changes.
(This implements the iterator based on index access, thus it will be slow for a linked list. Then better implement it based on AbstractSequentialList.)
Of course, the resulting list will obviously not be of the same class as the original list.
Use this solution only if you really only need a read-only two added view of your original list, not if you want a modified copy with similar properties.
The whole point of using an interface, in this case List, is to abstract the fact that the implementation is hidden behind the interface.
Your intention is clear to me, however: the Clonable interface supports creating a new instance with the same state. This interface might not be defined on your List.
Often it's a good idea to rethink this situation: why do you need to clone the List in this place, this class? Shouldn't your list-creator be responsible for cloning the list? Or shouldn't the caller, who knows the type, make sure he passes in a clone of his list?
Probably, if you look for the semantics as you defined it, you can implement all your supported Lists:
static Vector<Integer> addTwo(Vector<Integer> vector) {
Vector<Integer> copy = null; // TODO: copy the vector
return addTwo_mutable(copy);
}
static ArrayList<Integer> addTwo(ArrayList<Integer> aList) {
ArrayList<Integer> copy = null; // TODO: copy the array list
return addTwo_mutable(copy);
}
static LinkedList<Integer> addTwo(LinkedList<Integer> lList) {
LinkedList<Integer> copy = null; // TODO: copy the linked list
return addTwo_mutable(copy);
}
private <T extends List<Integer>> static T addTwo_mutable(T list) {
return list; // TODO: implement
}
Even, when you don't support a data-type, you'll get a nice compiler error that the specified method does not exists.
(code not tested)
Just to show you that what you want to do is not possible in the general case, consider the following class:
final class MyList extends ArrayList<Integer> {
private MyList() {
super.add(1);
super.add(2);
super.add(3);
}
private static class SingletonHolder {
private static final MyList instance = new MyList();
}
public static MyList getInstance() {
return SingletonHolder.instance;
}
}
It is a singleton (also, a lazy, thread-safe singleton by the way), it's only instance can be obtained from MyList.getInstance(). You cannot use reflection reliably (because the constructor is private; for you to use reflection, you'd have to rely on proprietary, non-standard, non-portable APIs, or on code that could break due to a SecurityManager). So, there's no way for you to return a new instance of this list, with different values.
It's final as well, so that you cannot return a child of it.
Also, it would be possible to override every method of ArrayList that would modify the list, so that it would be really an immutable singleton.
Now, why would you want to return the exact same implementation of List?
OK well someone mentioned reflection. It seems to be an elegant solution:
import java.util.*;
public class ListAdd {
static List<Integer> add2 (List<Integer> lst) throws Exception {
List<Integer> result = lst.getClass().newInstance();
for (Integer i : lst) result.add(i + 2);
return result;
}
}
Concise, but it thows an checked exception, which is not nice.
Also, wouldn't it be nicer if we could use the method on concrete types as well, e.g. if a is an ArrayList with values 1, 2, 3, we could call add2(a) and get an ArrayList back? So in an improved version, we could make the signature generic:
static <T extends List<Integer>> T add2 (T lst) {
T res;
try {
res = (T) lst.getClass().newInstance();
} catch (InstantiationException e) {
throw new IllegalArgumentException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
for (Integer i : lst) res.add(i + 2);
return res;
}
I think throwing a runtime exception is the least worst option if a list without a nullary construcor is passed in. I don't see a way to ensure that it does. (Java 8 type annotations to the rescue maybe?) Returning null would be kind of useless.
The downside of using this signature is that we can't return an ArrayList etc as the default, as we could have done as an alternative to throwing an exception, since the return type is guaranteed to be the same type as that passed in. However, if the user actually wants an ArrayList (or some other default type) back, he can make an ArrayList copy and use the method on that.
If anyone with API design experience reads this, I would be interested to know your thoughts on which is the preferable option: 1) returning a List that needs to be explicity cast back into the original type, but enabling a return of a different concrete type, or 2) ensuring the return type is the same (using generics), but risking exceptions if (for example) a singleton object without a nullary constructor is passed in?

hidding api with interfaces in Java

Can somebody explain me what "hidding api with interfaces in Java" means ?
How can I use the API functions by means of interfaces ?
I would need an small working example to understand the how the interfaces hides the api non public parts, and how can I use the api puplic parts in the same time.
Thanks in advance.
THANKS GUYS FOR THE QUICK REPLY, GIVE ME TIME TO THINK OVER THE ANSWERS.
LAST BUT NOT LEAST THANKS FOR YOUR TIME AND EFFORT!
II. My second question is : What happens in the background this case below ?
IBinaryOperation op = BinaryOperationProvider.getOperation("multiply");
or
List<String> myList = new LinkedList<String>();
Its not clear for me because the interfaces consist of methods' declarations that's why i dont understand what could happened in the lines above.
Is there any meaning of the equality between empty method of used interfaces and objects ?
Sorry for my weak English.
For instance, you may declare and create a list of strings as follows:
List<String> myList = new LinkedList<String>();
List is the type of myList. It is an interface. It means that all subsequent calls to methods of myList will be done through the interface: you may only call methods declared in the List interface.
However, the concrete class of the object is LinkedList, that contains more methods, some of them reflecting the structure of a linked list (for instance addFirst and addLast). But these methods are hidden because of the way you declared the variable. You chose to access the object through a given (restrictive) interface.
It may seem restrictive, but it also means that you can change your code at any time, and replace the concrete class LinkedList with any other class that implements the List interface, for example ArrayList.
Usually when you expose your API, you should hide the implementation details as much as possible and expose it via simple interfaces.
For e.g. Suppose that you give an api for adding two numbers.
Soln1 (Bad soln) Give the following class to client
public class Adder {
public void setA() {..}
public void setB() {..}
public int add() { return A + B; }
}
Soln 2 (better soln): Give the following interface to the client.
public interface Adder {
public int add(int a, int b);
}
Now why is soln 2 a better solution. If you had given user the first soln. The client is bound to the class Adder. Suppose later you have a new implementation of addition that could add the numbers in the cloud(over-imaginative :)), you may have to as the client to change their code to use the new class.
Instead if you just give them the interface, you could provide many implementation and have a factory mechanism to choose the suitable implementation.
Here's a very simple example that uses an interface:
public interface IBinaryOperation {
public int performOp(int a, int b);
}
private class MultiplicationProvider implements IBinaryOperation {
public int performOp(int a, int b) {
return a * b;
}
}
public class BinaryOperationProvider {
static IBinaryOperation getOperation(String name) {
if ("multiply".equals(name)) {
return new MultiplicationProvider();
} else if ("add".equals("name)) {
return new AdditionProvider();
} // ...
}
}
You would use this like:
IBinaryOperation op = BinaryOperationProvider.getOperation("multiply");
int c = op.performOp(a, b);
In the above example, MultiplicationProvider is completely private to the implementation of the API. The only public part is the IBinaryOperation interface, and the BinaryOperationProvider class.
Just to be clear, what's "hidden" is not the API, but the implementation. Most clients of List (to use an example above) don't need to know which kind of List is actually being used. (Just like most TCP/IP clients don't need to know anything in particular about the network they're using -- just that it supports the standard connection abstraction.)

Cast a List<> in java?

Hi is it possible to cast a List?
i have an abstract class that has a method that takes some sort of List<>, iterate through it in a for loop getting each object in that list and calling the insertItem abstract method that is implemented by the sub class to basically pull out the proper data in the items and then finaly inserting them into a database table.
here is the super class method:
protected void insertAllItemsToDb(List<Object> items, String table) {
// open db and table
database().beginTransaction();
// clear all data from table
clearTable(table);
// call a insert statement to insert each column from an item
for (Object object : items) {
insertItem(object, table);
}
// close db
database().endTransaction();
database().close();
}
In the subclass here is one of the override methods: Which i am able to cast the object fine here.
#Override
protected void insertItem(Object object, String table) {
CalendarEventItem item = (CalendarEventItem) object;
eventItemValue = new ContentValues();
eventItemValue.put(LABEL_EVENTS_TITLE, item.getEventTitle());
eventItemValue.put(LABEL_EVENTS_LOCATION, item.getEventLocation());
eventItemValue.put(LABEL_EVENTS_DATE, item.getEventStartTime()
.getDate());
eventItemValue.put(LABEL_EVENTS_TIME, item.getEventStartTime()
.getTime());
eventItemValue.put(LABEL_EVENTS_TIMEZONE, item.getEventStartTime()
.getTimeZone());
database.insert(TABLE_NAME_EVENTS, null, eventItemValue);
}
i then call that method from the superclass using this:
events = (List<CalendarEventItem>) items;
insertAllItemsToDb(events, TABLE_NAME_EVENTS);
But i recieve a compile error saying you cant cast it. Any ideas on how i can achieve this without having to duplicate the same steps and code you see inside the insertAllItemsToDb()
Use a Type parameter
Add a generic Parameter to the abstract class:
public abstract class BaseClass<T>{
protected abstract void insertItem(T object, String table);
protected void insertAllItemsToDb(List<T> items, String table) {
//...
for (T object : items) {
insertItem(object, table);
}
//...
}
}
Now you don't need any casting, a child class just has to use the correct type:
public class FooBar extends BaseClass<Phleem>{
protected void insertItem(Phleem object, String table){
// ...
}
}
A List<Object> is not a List<CalendarEventItem>, so the compiler is right that they aren't castable. For a quick reason why, here's an example:
final List<Object> listOne = new ArrayList<Object>();
listOne.add("Hello World");
final List<CalendarEventItem> listTwo = new ArrayList<CalendarEventItem>();
listTwo.addAll(listOne); // Correctly disallowed by compiler
// This is what you're trying to do
List<CalendarEventItem> sneakyList = (List<CalendarEventItem>)listOne;
listTwo.addAll(sneakyList);
So casting between two incompatible types is disallowed because it would destroy the type-safety guarantees.
You almost certainly want to be declaring your insertAllItemsToDb method to take a List<?> rather than a List<Object>, since you don't care what the element type is so long as it's a subclass of Object (which is trivially true).
This should prevent you having to cast between inconvertible types, and is generally much nicer to work with.
For more information take a look at the Wildcard Bounds section of Angelika Langer's excellent Java Generics FAQ. In fact, you should probably look over the whole thing if you haven't already. The general principle to take away is that in most cases you should likely use wildcards on collections used for method arguments - the only time you wouldn't is if you both read from and write to the collection (which is actually surprisingly rare).
You could also just declare the method parameter as a regular list and then cast it to whatever generic list you want inside the method, ie your method would be protected void insertAllItemsToDb(List items, String table) and the first line you would cast it: List<CalendarEventItem> newItems = (List<CalendarEventItem>) items... of course implementing whatever type of checking/error catching that you should when doing such a thing.

Hiding a constructor behind a static creator method?

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

Categories