In this post I suggested a solution that uses interface and anonymous class. However, there is one thing to be implemented: the hashCode and equals method.
However I found it is hard to implement equals for anonymous class that implements an interface. In that example the interface is Pair<L,R>, and a factory method Pairs.makePair will return an anonymous implementation for it. Suppose I added an equals implementation. The user may implement their own Pair<L,R> classes with a different equals code, therefore the call userobj.equals(makepairobj) will enter their code, and makepairobj.equals(userobj) will enter my code. Because I have no control of their code, it is hard to make sure equals to be symmetric, which is required for a good implementation.
I believe this problem is common for other cases, so I would like to know how this issue being address generally?
EDIT:
In typical class, the implementation of equals will check the parameter type to make sure it is the same as its own. This guarantee only the implementing code will be called to compare the objects. However, the anonymous class do not have a name and cannot check the type with instanceof. What I can do is make sure it is an instance of the implementing interface/class. Which is not enough to prevent the above scenario.
You can use this.getClass() (with either == or isAssignableFrom()) to compare the types.
Edit
As in:
public boolean equals(Object obj) {
if (getClass() == obj.getClass()) {
// do whatever
}
return false;
}
Usually, when you make an interface like this, it requires the implementing classes to implement equals and hashCode to follow some convention. For example, if you look at the java.util.List interface, it requires lists to be equal iff they have the same length and equal elements in the same order, and it specifies a formula for calculating the hashCode based on the hash codes of the elements.
So then "it is hard to make sure equals to be symmetric" should not be a problem.
The problem you've encountered is a sign that an anonymous class is the wrong way to implement this.
Anonymous classes are a simply a shorthand way of implementing an interface or extending a class. It's purely syntactic sugar, with no extra functionality or other advantage. They were (perhaps mistakenly) intended to make your code simpler and more readable. If an anonymous class complicates your code instead, don't use it.
Many cases that used to be a good fit for anonymous classes are now better served by lambdas. If a class has two or three methods, trying to put it in an anonymous class makes your code hard to read; it should be an inner class anyway.
Related
When using lombok #Data (which adds EqualsAndHashCode)
It adds canEqual method
protected boolean canEqual(Object other) {
return other instanceof Exercise;
}
which is only called once:
if (!other.canEqual((Object)this)) return false;
I search and found discussions about access level
If you implement equals and hashCode in a non-final class the safest thing we can do is add the can equal the way we do. Since we don't add any field the costs, especially if the method is protected, are slim.
But why do we need this generated method ? can't it be inline?
The canEqual method is defined in a paper entitled How to Write an Equality Method in Java. This method is meant for allowing to redefine equality on several levels of the class hierarchy while keeping its contract:
The idea is that as soon as a class redefines equals (and hashCode), it should also explicitly state that objects of this class are never equal to objects of some superclass that implement a different equality method. This is achieved by adding a method canEqual to every class that redefines equals.
Seems like it was introduced in Lombok 0.10, as described in the #EqualsAndHashCode documentation:
NEW in Lombok 0.10: Unless your class is final and extends java.lang.Object, lombok generates a canEqual method which means JPA proxies can still be equal to their base class, but subclasses that add new state don't break the equals contract.
And the documentation goes a bit further, referencing the paper quoted above:
The complicated reasons for why such a method is necessary are explained in this paper: How to Write an Equality Method in Java. If all classes in a hierarchy are a mix of scala case classes and classes with lombok-generated equals methods, all equality will 'just work'. If you need to write your own equals methods, you should always override canEqual if you change equals and hashCode.
I am implementing equals method for a class, which has a member of a Functional Interface type. I do not have a separate class for the concrete implementation of the interface, and I use lambda expression to create and set the interface variable. I want the equals method of the class to take into consideration, the code, which was provided via lambda expression. Different implementations must must not return equal. Is there a way to achieve this properly? Since I did not find any links related to this requirement I am doubting whether such a practice is recommended, even if it is possible to achieve the same. What is the best thing to do?
I understand what interfaces and abstract classes are, but I don't know how to get the following functionality; if it's possible, that is. I have a bunch of classes which are each going to have a validate() method. Each method may take different parameters. For example, we could have classes with the following methods:
boolean validate();
boolean validate(Block[]);
boolean validate(BlockSet[]);
...
So, basically I want to know if I can use an interface or abstract class, or something else, to define a contract to have a method with a given name and return type implemented, but no restrictions on the set of parameters. Thanks in advance.
You can do this with validate(Object... args), but it's worth questioning whether you really want to. Interfaces and Abstract Classes are useful so that you can group a bunch of similar objects together, and have implementations do different things with the same operation. It seems to me that you wouldn't be able to call this method without knowing what the underlying implementation is, and therefore there is no reason to abstract them.
Try using varargs in an interface:
boolean validate(Object... args) or
'boolean validate(Block... blocks)`
if the Blocks are always a collection, use their supertype:
boolean validate(Collection<Block> blocks)
But then you may need to use some casts. Not best option.
If you want method to take any number pf parameters then you can use Varargs but if you want it to change Type also then its not feasible.
Also what you want to achieve is find a separate way of method overloading, but for that you will have to explicitly specify the methods.
I want to override equals(Object o) without using instanceof, getClass() and casting. Is this doable in Java and if yes how it is possiable?
Editing: And I want to use this method too.
For example: I want to override this method in class Cow and use it to check if my Cow logically equals to other Cow?
Thanks for answers everyone. My main problem is that: what happens if I send Car as other class to my cow or any other Object. How can I check if Object o got method getName() (Assuming my Cow got this method)?
Sure.
Make Cow serializable, and make sure that its serialized form is canonical (worst case by implementing Externalizable and hand-writing your own serialization that is canonical) and then do the following in equals:
Try to serialize the argument. If that fails, return false.
Serialize this.
Compare the serialized bytes of the two.
Since the serial form includes a string identifying the type, it includes the bytes necessary to distinguish instances of different types.
This isn't easy, is inefficient, is probably a maintenance nightmare, and should definitely not be your first choice, but it does demonstrate that there are language tricks available to Java code that will allow type distinction without instanceof or Class sameness checks.
One caveat though: the serial form does not distinguish between classes with the same name loaded in different class loaders.
It's certainly possible if the criteria for equality are limited to using information that is only available from an Object.
This /seems/ unlikely... why would you be overriding equals if you were only using Object's methods? However, there's nothing to prevent you from doing it, if this is appropriate for your design.
Just be sure that you maintain the contract defined in the Javadocs for equals()
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How are Java interfaces actually used?
I'm not talking from an accademic buzzword point of view but from a pratical developer point of view.
So taking the example:-
Class1 implements Interface
public String methodOne() {
return "This is Class1.methodOne()";
}
public String methodTwo() {
return "This is Class1.methodTwo()";
}
}
Class2:
Class2 implements Interface
public String methodOne() {
return "This is Class2.methodOne()";
}
public String methodTwo() {
return "This is Class2.methodTwo()";
}
}
Using the Interface:-
Client {
Interface intface = new Class1();
intface.methodOne();
intface.methodTwo();
Interface intface = new Class2();
intface.methodOne();
intface.methodTwo();
}
But what are the benefits over just writting:-
Client {
Class1 clas1 = new Class1();
clas1.methodOne();
clas1.methodTwo();
Class2 clas2 = new Class2();
clas2.methodOne();
clas2.methodTwo();
}
And bypass the Interface altogether.
Interfaces just seem to be an additional layer of code for the sake of an additional layer of code,
or is there more to them than just "Here are the methods that the class you are accessing has"?
When using standalone classes, you don't need interfaces. However, when you have a type hierarchy, interfaces are indeed indispensable.
Your simple example does not really do justice, but let's rename your interface to something more useful and concrete, e.g. a Sorter algorithm which can take a list of items and sort them. You can have several different sorting algorithms implemented, and you may want to change the algorithm used, based on the context (i.e. QuickSort is faster for large data sets, but BubbleSort is better for small data sets, etc.) So you don't want to tie the client code to one specific algorithm. By using the polymorphic Sorter type (implemented as an interface), you can pass different concrete sorter objects to the client, without it knowing (and caring) what algorithm it is actually using. And you can any time introduce a better sorting algorithm, or remove one which proved inefficient, without the clients noticing anything.
Such a feat would be impossible without interfaces. The alternative would be calling the sort method of choice directly from (possibly duplicated) if-else or switch blocks all over the place, with the inevitable possibility of introducing bugs when forgetting to update all places properly when a sorting algorithm is added/removed... not to mention that you would need to recompile all client code after each such change :-(
Suppose you want a collection of objects with both methods "Method1" and "Method2".
And you don't want to programatically check each instance in the collection for its type.
A collection of objects the implement that interface saves you from doing this.
It calls Polymorphism and it is very useful.
The other folks have pretty much covered your question but, in a word: Yes!
The Java language was actually conceived as a fairly minimal object-oriented language, and interfaces were there from the very beginning. There are concepts of describing the relationships between classes that are hard or impossible to do without either interfaces or some performance-costly runtime type identification. All or almost all the patterns quoted in the famous Design Patterns book (here's the book itself) rely on interfaces.
(Not sure how I respond without it being seen as an answer but...)
Wow, so many answers so quickly, pretty impressive forum - cheers! :-D
So would it be reasonable to say that an Interface essentially sets the 'rules' for which the concrete classes must meet?
For example if I had classes Class1 & Class2, both of which have method 'getList()'.
Without implementing an Interface Class1.getList() could return say a list of Strings and Class2.getList() could return Integers.
Essentially the Interface sets the rules that my Class has to have a method of getList() and that method must return List,
so if both implement the Interface Lister with method 'public String getList();' I know that both Class1 & Class2 getList() returns a
List of types String.
But concrete Class1 could be returning a list of departments whereas Class2 is a list of employees, but I know they both return a list of Strings.
This would probably become more useful if I had maybe half dozen or so classes each with half dozen methods all of which I want to
ensure meet the .getList returns a list of type String 'rule'.
I use interfaces mostly for
simulating multiple inheritance
defining a service contract and a service implementation
single method callback contracts
and because
some dependency injection frameworks require interfaces to work
mocking interfaces easier than mocking classes
many AOP frameworks work better with interfaces than classes
And it is not really a layer of code between a service and its client, but more a formal contract.
Interfaces are useful if there is a chance that you'll need more than one implementation, maybe for another technology (different database) or for testing.
Interfaces define the contract of the type, without anu implementation details. This lets you program against the interface without knowing the actual implementation class.
An example of the advantage of interfaces using your code could be:
public void useInterface(Interface obj) {
obj.methodOne();
obj.methodTwo();
}
and calling it as in:
useInterface(new Class1());
useInterface(new Class2());
The Java collections classes make heavy use of interfaces, it allows you to switch implementations for lists and maps later without having to change the code using those instances.
Consider the following method which receives a list of 'intfaces', you don't have to know if you handle clas1 or clas2, you just want to handle something that 'is a' intface. You may add clas3 implement intface later on and it will stil work...
public void callMethods(List<intface> intfaces){
for(Interface intface : intfaces) {
intface.methodOne();
intface.methodTwo();
}
}