Why do Java introduces some interface which has no methods defined in it? For example Cloneable, Serializable, Type and many more.
Second thing : In Class.class package there is one method defined registerNatives() without body and is called from static block but Class.class is not abstract but is final. Why so?
and Why Java need some method without body to be called from static block.?
Why do Java introduces some interface which has no methods defined in it?
This are called Tagged or Marker interface. These are not used for any use or operation. These methods are used to tag or marking a class. So that you can determine whether someclass is a child of those classes.
about the second question
If you look closely you can see the declaration is
private static native void registerNatives();
So registerNatives is a native methods.
So what is native methods. If you see this so question
The method is implemented in "native" code. That is, code that does
not run in the JVM. It's typically written in C or C++.
Native methods are usually used to interface with system calls or
libraries written in other programming languages.
So these methods are loaded from native codes. So you don't need to declare the body of the methods but still they are not abstract as they have their implementation from native codes.
Marker interface is used as a tag to inform a message to the java compiler so that it can add special behavior to the class implementing it. Java marker interface has no members in it.
The purpose of Marker interfaces is to force some kind of functionality in the classes by providing some functionality to a class if it implements the marker interface.
Read Java Marker Interface also see What is the use of marker interfaces in Java?
For the first one you are actually asking for a Marker Interface. Marker Interfaces are by design not supposed to add anything to behavior but support only polymorphic transformation of the object. e.g. Serializable makes an object capable of streaming across JVM boundaries. Marker interfaces follow the 'universal type substitution' philosophy.
For second one, you are actually asking for JNI. Java doesnot implement all its code in Java form. I mean in classes and code that follow Java syntax. Some time or the other you need to drill down to the native platform API to implement something for that API. e.g. sockets and TCP communication. It is this feature of Java that actually makes it platform independent. The JVM runtime is platform dependent as it uses platform based native methods and dll or .so libraries to implement and integrate with the platform. We as programmers call the high level Java SDK API calls.
One of the "clean" features of the Java programming language is that it mandates a separation between interfaces (pure behavior) and classes (state and behavior). Interfaces are used in Java to specify the behavior of derived classes.
Often you will come across interfaces in Java that have no behavior. In other words, they are just empty interface definitions. These are known as marker interfaces. Some examples of marker interfaces in the Java API include:
java.lang.Cloneable
java.io.Serializable
java.util.EventListener
Marker interfaces are also called "tag" interfaces since they tag all the derived classes into a category based on their purpose. For example, all classes that implement the Cloneable interface can be cloned (i.e., the clone() method can be called on them). The Java compiler checks to make sure that if the clone() method is called on a class and the class implements the Cloneable interface. For example, consider the following call to the clone() method on an object o:
SomeObject o = new SomeObject();
SomeObject ref = (SomeObject)(o.clone());
If the class SomeObject does not implement the interface Cloneable (and Cloneable is not implemented by any of the superclasses that SomeObject inherits from), the compiler will mark this line as an error. This is because the clone() method may only be called by objects of type "Cloneable." Hence, even though Cloneable is an empty interface, it serves an important purpose.
registerNatives()
native method are implemented in JVM itself.
What does the registerNatives() method do?
Why Java need some method without body to be called from static block.?
This is called from static block because we need to call this method when classes are loaded and not when it's instance is created.
Related
Java 8 has included a new feature called Defender methods which allows creation of default method implementation in interface.
Now first of all this is a huge paradigm shift for all condensed programmers in Java. I viewed a JavaOne 13 presentation given by Brian Goetz where he was discussing about the new stream() and parallelStream() implementations in Collections library.
For adding new methods in Collection interface, they could not have just added a new method without breaking the previous versions. So he told that for catering this a new feature of Default methods was added.
public interface SimpleInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
default public void doSomeOtherWork(){
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
Now my question is basically that are default methods just helpful when needed to add new methods to interface without breaking client code? Or are there some other uses to it too?
Besides having the possibility of adding methods to the interface in future versions, there is the important point of allowing an interface to stay a functional interface even if it has more than one method.
A functional interface has only one non-default abstract method which can be implemented via a lambda expression. One example is the Predicate interface which has only one abstract method (test) while providing default methods for negating a Predicate or combining it with another Predicate. Without default methods these methods had to be provided in another utility class like the pre-Java 8 Collections class (as you don’t want to give up the possibility of lambda implementations for such an interface).
As you said, the main motivation was allowing the evolution of existing interfaces.
However there are reasons why you'd want to use them in brand new interfaces as well:
One such reason is methods that can easily be implemented using the other (non-default) methods of the interface. Using default methods for this reduces the need for Foo-interface/AbstractFoo-base-implementation combinations (see AbstractList for example).
While this does not create an entirely new field, it means that you can have end-user-friendly interfaces (with lots of useful methods), still keeping it simple to implement.
There was a problem with interfaces that they were not open to extension, which means if there was a need to add new method to an interface it would have broken the existing implementation of these interfaces. Thus it was imperative that all the classes implementing that interface had to provide implementation for the newly added method, even if the method was not needed. Thus interfaces were not easy to evolve.
One example that comes to mind is Java MapReduce API for Hadoop, which was changed in 0.20.0 release to favour abstract classes over interfaces, since they are easier to evolve. Which means, a new method can be added to abstract class (with default implementation), with out breaking old implementations of the class.
With the release of Java 8, it is now possible to add default method in interfaces also, thus making them easier to evolve too. With the addition of default method to an interface, addition of new method, to even an interface will not break the pre-existing code.
For adding new methods in Collection interface, they could not have
just added a new method without breaking the previous versions.
Yes they could have done this but Let's think from API designer perspective for e.g. Collection Library is used by some libraries like apache-commons, guava etc and which instead are used by many java projects. Now imagine just by adding one new method in Collection interface will break entire chain of projects.
Now my question is basically that are default methods just helpful
when needed to add new methods to interface without breaking client
code? Or are there some other uses to it too?
Motivation/Need for Default Methods
API Evolution in compatible way
The initial purpose of introducing default methods was to make collections library backward compatible. This library was modelled as a deep hierarchy of interfaces, including prominent members such as Collection, List, Map, and Set. They needed to be enriched to make lambdas truly useful for everyday programming.
To make Collections library lambda rich, java architects could have
refactored them to support lambda but it was a far from a good
solution as it will break all the all existing Java deployments and
countless 3rd party libraries extending the Collections hierarchy
Instead java architects thought to introduce default methods capabilities for backward compatibility.
Use cases of Default Methods
One important use case is to aid functional thinking in java. A functional interface with default methods is a pure behaviour-only construct. It cannot hold state. This aligns your thinking with functional programming and allows you to take advantage of what the programming model has to offer
Optional Methods : There are classes in java that implement an interface but leave empty method implementations for e.g. Iterator interface. It defines hasNext and next but also the remove method. Prior to Java8 remove was ignored because the user didn't want to use that capablity. Therefore many classes implementing Iterator interface would have empty implementation of for remove which is unnecessary boiler plate code. With default methods we can provide a default implementation for such methods, so concrete classes don't need to explicitly provide an empty implementation.
Default methods helps in resolving Multiple inheritance of behaviour in java. Before Java8, there was support for Multiple inheritance of Type only and now with the help of default methods we can have multiple inheritance of behaviour.
For e.g.
Java 8 has three rules for resolving conflicts brought upon by
multiple inheritance when ambiguous:
First, an explicit method declaration in the class or a superclass takes priority over any default method declaration.
Otherwise, the method with the same signature in the most specific default providing interface is selected.
Finally, if there is still conflict, you have to explicitly override the default methods and choose which one your class should choose.
In Conclusion Default methods offer a brand new way to design objects.
References :
Java8 In Action
Functional Java: A Guide to Lambdas and Functional Programming in Java 8
default methods made possible the functional programming concept. For functional programming type code we need only one abstract method .
Also adding an method in interface will not made it compulsory for all the classes implementing an interface. Simplified the coding practise
I am perplexed. I read some threads on stack-overflow regarding marker interfaces in JAVA.
On this thread it is written as:
Marker interfaces aren't 'identified by the JVM' at all. They're identified by the Java code that is interested in them, for example ObjectOutputStream, via the instanceof operator.
Then in comments, it is asserted that:
The implementation in ObjectOutputStream checks if the object has implemented the Serializable interface, if yes perform wirteObject(objectToBeSerialized). So even we can write a marker interface and write a code that checks if an object is an instance of that marker interface and take appropriate action on it then.
On another thread it is written as:
Only Serializable will mark an object as being compatible with Java's built-in serialization machinery.
You can create other empty interfaces, but they won't mean the same thing. Each interface is distinct, even if it defines the same set of methods.
So my question is can we make classes that use serialization without implementing corresponding JAVA's built in interface?
Or is it a special interface that is mandatory to be implemented?
(Asumme, I don't want to use instance of)
Learning java 8 default methods .
This link like any other resource on internet says
In ‘the strictest sense’, Default methods are a step backwards because
they allow you to ‘pollute’ your interfaces with code. But they
provide the most elegant and practical way to allow backwards
compatibility. It made it much easier for Oracle to update all the
Collections classes and for you to retrofit your existing code for
Lambda.
My understanding is that java 8 dev/designers provided the default method in interfaces so that all implementing class does not have to unnecessarily
override same behavior, hence provide backward compatibility. For example :- if ForEach method would not have been default method, every collection implementing class had to implement it. Agreed .
To overcome that we could have had one class providing implementation of these default methods and then implementing class like arraylist etc could
have extended that. This way we could have statisfy both java fundamentals i.e reusability and abstraction i.e keeping the interface pollution less
I am sure java 8 dev/designer have already thought about this as they are much more learned and i am missing something here. Can someone help here so that we developers can also be on top of it as this major change?
Before Java 8, interfaces could have only abstract methods. The implementation of these methods has to be provided in a separate class. So, if a new method is to be added in an interface then its implementation code has to be provided in the class implementing the same interface.
To overcome this issue, Java 8 has introduced the concept of default methods which allow the interfaces to have methods with implementation without affecting the classes that implement the interface.
The default methods were introduced to provide backward comparability so that existing interfaces can use the lambda expressions without implementing the methods in the implementation class. Default methods are also known as defender methods or virtual extension methods.
To overcome that we could have had one class providing implementation of these default methods and then implementing class like arraylist etc could have extended that.
Your suggestion would work only for standard JDK classes (since they usually extends some base classes such as AbstractCollection and AbstractList, were the implementation of the new methods can be added).
What about custom classes that implement JDK interfaces? If, for example, you have a class that implements List but doesn't extend some JDK List implementation, you should be able to switch to Java 8 without having to implement new methods in your class.
With default implementations of new methods in the List interface, you don't have to touch your custom class. You can later add a custom implementation to those methods if you are not satisfied by the default implementation.
If there is a requirement to add new method to an interface, clients which use existing interface will be broken as classes needs to implement all methods in the interface.
In this scenario, default and static methods can be used. These methods can have body and clients don't need to implement them, so existing implementations work without any changes.
For example, if you want to enhance interfaces to add methods which accept lambda expressions, you can use default methods.
I am looking for a java equivalent to the C# extension methods feature. Now I have been reading about Java 8's default methods, but as far as I can see, I can only add these to interfaces...
...is there any language feature that will allow me to write an extension method for a final class that doesn't implement an interface? (I'd rather not have to wrap it...)
Java doesn't have extension methods. Default methods are not extension methods. Let's look at each feature.
Default methods
Both Java and C# support this feature
Problems solved:
Many objects may implement the same interface and all of them may use the same implementation for a method. A base class could solve this issue but only if the interface implementors don't already have a base class as neither java nor C# support multiple inheritance.
An API would like to add a method to an interface without breaking the API consumers. Adding a method with a default implementation solves this.
Java's or C#'s default methods are a feature to add a default implementation to an interface. So objects that extend an interface don't have to implement the method, they could just use the default method.
interface IA { default public int AddOne(int i) { return i + 1; } }
Any object that implements IA doesn't have to implement AddOne because there is a default method that would be used.
public class MyClass implements IA { /* No AddOne implementation needed */ }
C# now has this feature in C# 8 (or .Net 5)
C#'s Extension Method
Problems solved:
Ability to add methods to sealed classes.
Ability to add methods to classes from third-party libraries without forcing inheritance.
Ability to add methods to model classes in environments where methods in model classes are not allowed for convention reasons.
The ability for IntelliSense to present these methods to you.
Example: The type string is a sealed class in C#. You cannot inherit from string as it is sealed. But you can add methods you can call from a string.
var a = "mystring";
a.MyExtensionMethed()
Java lacks this feature and would be greatly improved by adding this feature.
Conclusion
There is nothing even similar about Java's default methods and C#'s extension method features. They are completely different and solve completely different problems.
C# extension methods are static and use-site, whereas Java's default methods are virtual and declaration-site.
What I believe you are hoping for is the ability to "monkey-patch" a method into a class you do not control, but Java does not give you that (by design; it was considered and rejected.)
Another benefit of default methods over the C# approach is that they are reflectively discoverable, and in fact from the outside, don't look any different from "regular" interface methods.
One advantage of C#'s extension methods over Java's default methods is that with C#'s reified generics, extension methods are injected into types, not classes, so you can inject a sum() method into List<int>.
Above all, the main philosophical difference between Java's default methods and C#'s extension methods is that C# lets you inject methods into types you do not control (which is surely convenient for developers), whereas Java's extension methods are a first-class part of the API in which they appear (they are declared in the interface, they are reflectively discoverable, etc.) This reflects several design principles; library developers should be able to maintain control of their APIs, and library use should be transparent -- calling method x() on type Y should mean the same thing everywhere.
C# extension methods are just syntactic sugar for static methods that take the extended type as first argument. Java default methods are something completely different. To mimic C# extension methods, just write usual static methods. You will not have the syntatic sugar, however; Java does not have this feature.
Java default methods are real virtual methods. For example, they can be overridden. Consider a class X inheriting from an interface I that declares a default foo() method. If X or any of its super classes declares no own foo() method, then X will get the foo() implementation of I. Now, a subclass Y of X can override X.foo() like a usual method. Thus, default methods are not only syntactic sugar. They are real extensions of the method overriding and inheritance mechanism that cannot be mimicked by other language features.
Default methods even require special VM support, so they are not even a compiler only feature: During class loading, the hierarchy of a class has to be checked to determine which default methods it will inherit. Thus, this decision is made at runtime, not at compile time. The cool thing about it is that you do not have to recompile a class when an interface it inherits gets a new default method: The VM will, at class load time, assign that new method to it.
It is possible to have extension methods with some tricks.
You may give a try to Lombok or XTend. Although extension methods don't come with the out of the box Java implementation, both Lombok and XTend offers a fully working solution.
Lombok is a simple standalone code processing framework, which makes most of the criticized Java specific hassle less painful, including extension methods:
https://projectlombok.org/features/experimental/ExtensionMethod.html
Xtend http://www.eclipse.org/xtend/ goes a few lightyears forward, and implements a language which is a combination of the best parts of modern languages such as Scala on top of Java and Java type system. This allows implementing some classes in Xtend and others in Java within the same project. The Xtend code complies to valid Java code, so no JVM magic happens under the hood. On the other hand, it is a little too much if you have only extension methods missing.
JPropel https://github.com/nicholas22/jpropel-light implements LINQ style extension methods in Java using Lombok. It may worth of a peek :)
I am trying to change an interface in Proj2.
However, Proj1 is already using this interface, and won't be compiled with my new version.
Looks like problems occur only if I change/delete existing methods but adding new methods seems to be not causing any issues.
So as long as I only "add" methods to the interface, I can expect Proj1 to be fine with the latest Jar of Proj2.
Is that a rock solid safe assumption?
Update:
Both the interface and impl reside in proj2. Proj1 has no implementation of that that interface.
By "using," you mean "references an object using the interface and invokes interface-defined methods using that reference," not "implements the interface" (yes, you've clarified in comments, but I just want to repeat, because all the other answers are about implementing the interface).
In that case, as long as you have not removed methods from the interface or change their signature, your existing code will work.
The reason that this will work is that the compiler translates the method calls into an invokeinterface bytecode, which references the interface class and method by name. At runtime, the JVM simply validates that the actual reference implements the interface, and invokes the method.
If you remove or change a referenced interface method, one of two things will happen: either the JVM will refuse to load the class in proj1, because the interface reference could not be resolved, or it will give a NoSuchMethodError (I believe it's the second). Same thing if you remove or change a referenced method in a concrete class.
No. Adding new methods to the interface or updating its current signature would require you to provide the implementation of those methods in classes where you have implemented the interface.
However, when you remove a particular method declaration from an interface, even though it is defined in the class implementing the interface, there would be no effect. The removed method would just serve to be a normal method of the class, no longer tied with the existing contract of the interface.
The only way that I can think of solving your issue is to take the advantage of Java letting you implement multiple interfaces for a given class. What you should try to do is create a new interface, define your new methods over here and let your classes in proj2 implement this interface as well. This way, when you package your new jar, your existing classes in proj1 would remain unaffected.
If you're just adding methods, create a second interface. Java classes can implement more than one interface. That way, the classes that implement Interface1 remain the same.
Your newer class(es) implement interfaces Interface1 and Interface2.
you will get the error:
The type XXXImpl must implement the inherited abstract method IXXX.method()