Why do we have separate Spliterators class in Java 8? - java

Why did new Spliterators class appear in Java 8? Since Java 8 we have possibility to add static methods to the interfaces.
Since Spliterators class has only static method wouldn't be simpler to declare all its methods in the Spliterator interface?
The same question about Collectors/Collector pair.
Thank you.

It’s perfectly possible that this decision was made without even thinking about this brand new possibility, but simply following the established-since-twenty-years pattern.
Besides that, it can be debated whether it is really useful to add 25 to 30 static methods to an interface. It makes sense to offer a few factories for canonical implementations, but you should draw a line somewhere. It’s not feasible to add factories to all implementations to an interface, just because they are offered by the same library. But this debate would be off-topic.
Further, Spliterators does not only offer static methods, but also nested classes. Unlike static methods, these classes would pollute the name space of every implementation class, when being defined in an interface.
Collectors and Spliterators may also contain implementation-specific non-public methods and even fields.

No, is not good idea, because interface declares a contract, but class represents logic. But after add default method to interface in Java 8 we can only declare public method, but in abstract class we can add public and private abstract method, so we still can hide some logic in abstract classes. Imagine, in actual level of language you can declare only public method, and everyone can change your idea for e.q. Collection

Because there is a difference between an interface and a class. These two have different intentions. Interface declares a contract. Default methods for the interface should be used carefully, for instance, where you can't break compatibility by adding a method declaration into an interface and can't declare xxxV2 interface.
A class is an entity, which represents a unit of the program logic.

Related

Static Factory method Advantages

I was reading effective java and one advantage of static factory methods written is that they can return an object of any sub-type of return type.
I understood the way we can implement this as mentioned in following link with example.
https://www.slideshare.net/mysky14/java-static-factory-methods
But in the book an example of Collections API is given that has static factory methods in java.util.Collections utility class and it is written that "Collections API is much smaller than it would have been had it exported 32 separate public classes".
It is also mentioned that in this manner, API can return objects without their classes to be public and this results in very compact API.
I want to know how the API size is reduced by implementing this method and not having separate public classes.
I want to know how the API size is reduced by implementing this method and not having separate public classes.
Let's use the same concrete example used in the book: java.util.EnumSet has static factories that return one of two implementations: RegularEnumSet or JumboEnumSet. These implementations have their own complexities, but are effectively hidden to the clients of Collections. In theory, the factories could use other implementations in the future, and the clients of them would not be affected.
If you visualized this in a class diagram, the factory methods (e.g., of(), as opposed to a constructor) return an abstract type EnumSet, which hides the details of the implementations. Abstract (or Interface) types effectively abstract (simplify) the API.
What's more, the implementations are actually package private, meaning they're declared without a public keyword. This means that only classes in the same package can see them, so it prevents having Client depend on them. This is a great example of information hiding, which allows API developers to simplify their API and also to change the hidden parts later without breaking the code.
Another example that comes to mind where factory methods can simplify an API are the concrete iterators in Collections. In this case, it's a factory method that is not static, e.g., ArrayList.iterator(), that returns a concrete iterator for ArrayLists. The name of this class is even less "known" than the EnumSet implementations.
In general having static factory method would take out your object instantiation logic out of your class. Suppose based on certain logic, you need to return different subclass objects. This would result in if-else logic in your class method whichever is responsible for appropriate object instantiation. Moving this out to static factory method would result in cleaner class design which would be easier to test and closer to "Closed to modification" principle

Does Java have plan that default method (java8) Substitute for Abstract Class?

Does Java have plan that default method substitute for Abstract Class?
I could not find a real case to use default method instead of Abstract?
There are no such plans, which you can derive from comparing the already documented intentions, which differ from the implications of such a plan:
Stuart Marks writes:
The main goal is to allow interface evolution, that is, the addition of new methods. If a new method is added to an interface, existing classes that implement the interface would be missing an implementation, which would be incompatible. To be compatible, an implementation has to come from somewhere, so it is provided by default methods.
…
The main intent of a Java interface is to specify a contract that any class can implement without having to alter its position in the class hierarchy. It's true that, prior to Java 8, interfaces were purely abstract. However, this is not an essential property of interfaces. Even when default methods are included, an interface at its heart still specifies a contract upon the implementing class. The implementing class can override default methods, so the class is still in complete control of its implementation. (Note also that default methods cannot be final.)
and Brian Goetz writes:
The proximate reason for adding default methods to interfaces was to support interface evolution, …
Here are some use cases that are well within the design goals:
Interface evolution. Here, we are adding a new method to an existing interface, which has a sensible default implementation in terms of existing methods on that interface. An example would be adding the forEach method to Collection, where the default implementation is written in terms of the iterator() method.
"Optional" methods. Here, the designer of an interface is saying "Implementors need not implement this method if they are willing to live with the limitations in functionality that entails". For example, Iterator.remove was given a default which throws UnsupportedOperationException; since the vast majority of implementations of Iterator have this behavior anyway, the default makes this method essentially optional. (If the behavior from AbstractCollection were expressed as defaults on Collection, we might do the same for the mutative methods.)
Convenience methods. These are methods that are strictly for convenience, again generally implemented in terms of non-default methods on the class. The logger() method in your first example is a reasonable illustration of this.
Combinators. These are compositional methods that instantiate new instances of the interface based on the current instance. For example, the methods Predicate.and() or Comparator.thenComparing() are examples of combinators.
Note that these do not target the primary domain of abstract classes, like providing a skeleton implementation. Besides the technical differences, abstract classes are semantically different as they bear design decisions about how to implement the functionality, which interfaces, even with default methods, should not. E.g. a well-known example is the List interface, for which two fundamentally different abstract classes exist, AbstractList and AbstractSequentialList and the choice of subclasses either or implementing List entirely different should not be foreclosed by the interface. So the List interface defines the contract and can never be a substitute for an abstract class, which provides a particular base implementation.
Other answers, and links to additional materials, have already adequately covered the technical differences between interfaces and abstract classes. What hasn't been covered well is why to use one over the other.
Consider two different ways to use a class or interface in Java: as a caller or as a subclasser. A caller has an object reference and can call public methods and access public fields via that reference. A subclasser can also access, call, and override protected members of the superclass. Classes can have protected members, but interfaces cannot.
A common question seems to be, now that we have default methods, why do we need abstract classes? A default method is part of what the interface presents to callers. A protected method on a class is not available to callers; it is only available to subclassers. Thus, if you want to share implementation with subclassers, then use a class (or abstract class) and define protected members and fields.
The protected mechanism allows a class to communicate with subclassers, distinct from the way it communicates with callers.
But the OP asks the opposite question: why would one use default methods in preference to abstract classes? In the situation where you actually have a choice (i.e., your abstraction doesn't require state, or protected methods, or any of the things that abstract classes have that interfaces do not), interfaces with default methods are far less constraining than abstract classes. You can only inherit from one class; you can inherit from many interfaces. So interfaces with default methods can behave like stateless traits or mixins, allowing you to inherit behavior from multiple interfaces.
Given that interfaces and abstract classes are used for different purposes, there is no plan to remove or replace anything.
Default methods can't substitute abstract classes, as abstract classes can (and often do) have fields. Interfaces can only contain behaviour and not state, which is unlikely to change in the future as multiple inheritance of state in Java is seen (rightly or wrongly) as evil.
They can also have final methods, which is another thing you can't mimic with default methods.
If anything, interfaces with default methods resemble traits rather than abstract classes, but the match isn't perfect. Using interfaces as traits is something that has to be done very carefully and knowing the limitations they come with. (Such as any implementing class can override a default method, potentially ruining the trait.)
More on this here.
One of the reasons why default methods in interfaces were introduced was to allow adding new methods to the JDK interfaces.
Without this feature once a class has been compiled with a specific version of an interface no new methods can be added to this interface. With the default methods in interfaces feature interfaces can be changed.

Reason for adding default and static methods in interfaces

Java 8 introduced default and static methods on interfaces. So now you can have concrete implementations in your interface whether using default or static methods.
The reason Java claimed to add these two new kind of methods is "ensure binary compatibility with code written for older versions of those interfaces".
My question:
Why to distort the interface original concept that suppose to be
fully abstract in order to support existing architectural problems?
What is the difference between using an abstract class and the new version of the interface other than the ability of a class to extend multiple interfaces?
The reason java claimed to add these 2 new kind of methods is "ensure binary compatibility with code written for older versions of those interfaces".
This applies only to default methods (not static methods) and omits some context. From Goetz, State of the Lambda:
The purpose of default methods ... is to enable interfaces to be evolved in a compatible manner after their initial publication.
The main goal is to allow interface evolution, that is, the addition of new methods. If a new method is added to an interface, existing classes that implement the interface would be missing an implementation, which would be incompatible. To be compatible, an implementation has to come from somewhere, so it is provided by default methods.
Why to distort the interface original concept that suppose to be fully abstract in order to support existing architectural problems?
The main intent of a Java interface is to specify a contract that any class can implement without having to alter its position in the class hierarchy. It's true that, prior to Java 8, interfaces were purely abstract. However, this is not an essential property of interfaces. Even when default methods are included, an interface at its heart still specifies a contract upon the implementing class. The implementing class can override default methods, so the class is still in complete control of its implementation. (Note also that default methods cannot be final.)
What is the difference between using an abstract class and the new version of the interface other than the ability of a class to extend multiple interfaces?
The ability of a class to extend multiple interfaces is closely related to another difference between interfaces and abstract classes, namely that interfaces cannot contain state. This is the primary difficulty with allowing multiple inheritance: if a superclass were to appear multiple times in the ancestry of a class, would that superclass' state appear just once or several times? (This is the so-called "diamond problem.")
Another difference is that abstract classes can define methods and fields to be shared with subclasses, but not with callers, by using protected and package-private access levels. Interfaces can have only public methods.
(In Java 9, support for private methods has been added. This is useful for implementation sharing among default or static methods of an interface.)
Finally, static methods in interfaces don't affect class inheritance, nor are they part of the interface's contract. They are merely a way of organizing utility methods in more convenient fashion. For example, a common use of static methods in an interface is for static factory methods. If static methods weren't allowed in interfaces, static factory methods would have to be put on a companion class. Allowing static methods in interfaces lets such methods be grouped with the interface itself, when doing so is appropriate.
The problem is, that you can never extend an Interface with a new method without breaking compatibility. Existing classes would not implement the method and therefore not run with the new version of code which use this method.
This was a major problem for the Java Class Library itself as it cannot add often asked for methods in basic interfaces (like Collections). This was the main driver for implementing default methods for interfaces.
The difference between this new method and using an abstract class (which is a quite good pattern for this problem in some cases) is, that you cannot inherit from multiple abstract classes. But you can easily implement multiple interfaces.
The static methods in interfaces are less clear, I think they are here to help you implement the default methods (if two default methods have same code, they both can call to a static method).

Java Code Style -- Interfaces vs. Abstract Classes

A new collaborator of mine who was reviewing some code I'd written told me that she wasn't used to seeing interfaces used directly in Java code, e.g.:
public interface GeneralFoo { ... }
public class SpecificFoo implements GeneralFoo { ... }
public class UsesFoo {
GeneralFoo foo = new SpecificFoo();
}
instead, expecting to see
public interface GeneralFoo { ... }
public abstract class AbstractFoo implements GeneralFoo { ... }
public class SpecificFoo extends AbstractFoo { ... }
public class UsesFoo {
AbstractFoo foo = new SpecificFoo();
}
I can see when this pattern makes sense, if all SpecificFoos share functionality through AbstractFoo, but if the various Foos have entirely different internal implementations (or we don't care how a specific Foo does Bar, as long as it does it), is there any harm in using an interface directly in code? I realize this is probably a tomato/tomato thing to some extent, but I'm curious if there's an advantage to the second style, or disadvantage to the first style, that I'm missing.
If you have no need for an abstract class with certain details common to all implementations, then there's no real need for an abstract class. Complexity often gets added to applications because there is some perceived need to support future features that haven't yet been defined. Stick with what works, and refactor later.
No, she's inexperienced, not right. Using interfaces is preferred, and writing redundant abstract super classes for the sake of redundancy is redundant.
UsesFoo should care about the behaviour specified by the interface, not about the super class of its dependencies.
For me "she wasn't used to" is not good enough reason. Ask her to elaborate on that.
Personally I'd use your solution, because:
AbstractFoo is redundant and ads no value in current situation.
Even if AbstractFoo was needed (for some additional functionality), I'd always use lowest needed type: if GeneralFoo was sufficient, then I'd use that, not some class derived from it.
It depends only on your problem.
If you use interfaces only, then if all your classes have a same method, it would have to be implemented redundantly (or moved away to a Util class).
On the other hand, if you do write an intermediary abstract class, you solved that problem, but now your subclass may not be a subclass of another class, because of absence of multiple inheritance in Java. If it was already necessary to extend some class, this is not possible.
So, shortly - it's a trade off. Use whichever is better in your particular case.
There is not harm in directly using an interface in code. If there were, Java would not have interfaces.
The disadvantages of using an interface directly include not being able to reach and class-specific methods which are not implemented in the interface. For poorly written interfaces, or classes which add a lot of "other" functionality, this is undesirable as you lose the ability to get to needed methods. However, in some cases this might be a reflection of a poor design choice in creating the interface. Without details it is too hard to know.
The disadvantages of using the base class directly include eventually ignoring the interface as it is not frequently used. In extreme cases, the interface becomes the code equivalent of a human appendix; "present but providing little to no functionality". Unused interfaces are not likely to be updated, as everyone will just use the base abstract class directly anyway. This allows your design to silently rot from the viewpoint of anyone who actually tries to use the interface. In extreme cases, it is not possible to handle an extending class through the interface to perform some critical functionality.
Personally, I favor returning classes via their interface and internally storing in members them via their lowest sub-class. This provides intimate knowledge of the class within the class's encapsulation, forces people to use the interface (keeping it up-to-date) externally, and the class's encapsulation allows possible future replacement without too much fuss.
I'm curious if there's an advantage to the second style, or disadvantage to the first style, that I'm missing
That reasons for the first interfaces style:
Often, the design is such that the interface is the public interface of the concept while the abstract class is an implementation detail of the concept.
For example, consider List and AbstractList in the collection framework. List is really what clients are usually after; fewer people know about about AbstractList because its an implementation detail to aid suppliers (implementers) of the interface), not clients (users) of the class.
The interface is looser coupling, therefore more flexible to support future changes.
Use the one that more clearer represents the requirement of the class, which is often the interface.
For example, List is often used rather than AbsrtactList or ArrayList. Using the interface, it may be clearer to a future maintainer that this class needs some kind of List, but it does not specifically need an AbstractList or an ArrayList. If this class relied on some AbstractList-specific property, i.e. it needs to use an AbstractList method, then using AbstractList list = ... instead of List list = ... may be a hint that this code relies on something specific to an AbstractList .
It may simplify testing/mocking to use the smaller, more abstract interface rather than to use the abstract class.
It is considered a bad practice by some to declare variables by their AbstractFoo signatures, as the UsesFoo class is coupled to some of the implementation details of foo.
This leads to less flexibility - you can not swap the runtime type of foo with any class that implements the GeneralFoo interface; you can only inject instances that implement the AbstractFoo descendant - leaving you with a smaller subset.
Ideally it should be possible for classes like UsesFoo to only know the interfaces of the collaborators they use, and not any implementation details.
And of course, if there is no need to declare anything abstract in a abstract class AbstractFoo implements GeneralFoo - i.e. no common implementation that all subclasses will re-use - then this is simply a waste of an extra file and levels in your hierarchy.
Firstly I use abstract and interface classes plentifully.
I think you need to see value in using an interface before using it. I think the design approach is, oh we have a class therefore we should have an abstract class and therefore we should have interfaces.
Firstly why do you need an interface, secondly why do you have an abstract class. It seems she may be adding things, for adding things sake. There needs to be clear value in the solution otherwise you are talking about code that has no value.
Emperically there you should see the value in her solution. If there is no value the solution is wrong, if it cant be explained to you she does not understand why she is doing it.
Simple code is the better solution and refactor when you need the complexity, flexibility or whatever perceived value she is getting from the solution.
Show the value or delete the code!
Oh one more thing have a look at the Java library code. Does that use the abstract / interface pattern that she is applying .. NO!

Why do many Collection classes in Java extend the abstract class and implement the interface as well?

Why do many Collection classes in Java extend the Abstract class and also implement the interface (which is also implemented by the given abstract class)?
For example, class HashSet extends AbstractSet and also implements Set, but AbstractSet already implements Set.
It's a way to remember that this class really implements that interface.
It won't have any bad effect and it can help to understand the code without going through the complete hierarchy of the given class.
From the perspective of the type system the classes wouldn't be any different if they didn't implement the interface again, since the abstract base classes already implement them.
That much is true.
The reason they do implement it anyways is (probably) mostly documentation: a HashSet is-a Set. And that is made explicit by adding implements Set to the end, although it's not strictly necessary.
Note that the difference is actually observable using reflection, but I'd be hard-pressed to produce some code that would break if HashSet didn't implement Set directly.
This may not matter much in practice, but I wanted to clarify that explicitly implementing an interface is not exactly the same as implementing it by inheritance. The difference is present in compiled class files and visible via reflection. E.g.,
for (Class<?> c : ArrayList.class.getInterfaces())
System.out.println(c);
The output shows only the interfaces explicitly implemented by ArrayList, in the order they were written in the source, which [on my Java version] is:
interface java.util.List
interface java.util.RandomAccess
interface java.lang.Cloneable
interface java.io.Serializable
The output does not include interfaces implemented by superclasses, or interfaces that are superinterfaces of those which are included. In particular, Iterable and Collection are missing from the above, even though ArrayList implements them implicitly. To find them you have to recursively iterate the class hierarchy.
It would be unfortunate if some code out there uses reflection and depends on interfaces being explicitly implemented, but it is possible, so the maintainers of the collections library may be reluctant to change it now, even if they wanted to. (There is an observation termed Hyrum's Law: "With a sufficient number of users of an API, it does not matter what you promise in the contract; all observable behaviors of your system will be depended on by somebody".)
Fortunately this difference does not affect the type system. The expressions new ArrayList<>() instanceof Iterable and Iterable.class.isAssignableFrom(ArrayList.class) still evaluate to true.
Unlike Colin Hebert, I don't buy that people who were writing that cared about readability. (Everyone who thinks standard Java libraries were written by impeccable gods, should take look it their sources. First time I did this I was horrified by code formatting and numerous copy-pasted blocks.)
My bet is it was late, they were tired and didn't care either way.
From the "Effective Java" by Joshua Bloch:
You can combine the advantages of interfaces and abstract classes by adding an abstract skeletal implementation class to go with an interface.
The interface defines the type, perhaps providing some default methods, while the skeletal class implements the remaining non-primitive interface methods atop the primitive interface methods. Extending a skeletal implementation takes most of the work out of implementing an interface. This is the Template Method pattern.
By convention, skeletal implementation classes are called AbstractInterface where Interface is the name of the interface they implement. For example:
AbstractCollection
AbstractSet
AbstractList
AbstractMap
I also believe it is for clarity. The Java Collections framework has quite a hierarchy of interfaces that defines the different types of collection. It starts with the Collection interface then extended by three main subinterfaces Set, List and Queue. There is also SortedSet extending Set and BlockingQueue extending Queue.
Now, concrete classes implementing them is more understandable if they explicitly state which interface in the heirarchy it is implementing even though it may look redundant at times. As you mentioned, a class like HashSet implements Set but a class like TreeSet though it also extends AbstractSet implements SortedSet instead which is more specific than just Set. HashSet may look redundant but TreeSet is not because it requires to implement SortedSet. Still, both classes are concrete implementations and would be more understandable if both follow certain convention in their declaration.
There are even classes that implement more than one collection type like LinkedList which implements both List and Queue. However, there is one class at least that is a bit 'unconventional', the PriorityQueue. It extends AbstractQueue but doesn't explicitly implement Queue. Don't ask me why. :)
(reference is from Java 5 API)
Too late for answer?
I am taking a guess to validate my answer. Assume following code
HashMap extends AbstractMap (does not implement Map)
AbstractMap implements Map
Now Imagine some random guy came, Changed implements Map to some java.util.Map1 with exactly same set of methods as Map
In this situation there won't be any compilation error and jdk gets compiled (off course test will fail and catch this).
Now any client using HashMap as Map m= new HashMap() will start failing. This is much downstream.
Since both AbstractMap, Map etc comes from same product, hence this argument appears childish (which in all probability is. or may be not.), but think of a project where base class comes from a different jar/third party library etc. Then third party/different team can change their base implementation.
By implementing the "interface" in the Child class, as well, developer's try to make the class self sufficient, API breakage proof.
In my view,when a class implements an interface it has to implement all methods present in it(as by default they are public and abstract methods in an interface).
If we don't want to implement all methods of interface,it must be an abstract class.
So here if some methods are already implemented in some abstract class implementing particular interface and we have to extend functionality for other methods that have been unimplemented,we will need to implement original interface in our class again to get those remaining set of methods.It help in maintaining the contractual rules laid down by an interface.
It will result in rework if were to implement only interface and again overriding all methods with method definitions in our class.
I suppose there might be a different way to handle members of the set, the interface, even when supplying the default operation implementation does not serve as a one-size-fits-all. A circular Queue vs. LIFO Queue might both implement the same interface, but their specific operations will be implemented differently, right?
If you only had an abstract class you couldn't make a class of your own which inherits from another class too.

Categories