Poll: Correct behavior of equality when passed object does not match LHS type? - language-agnostic

I asked a related question about findbugs, but let's ask a more general question.
Suppose that I am working with an object-oriented language in which polymorphism is possible.
Suppose that the language supports static type checking (e.g., Java, C++)
Suppose that the language does not allow variance in parameters (e.g., Java, again...)
If I am overriding the equality operation, which takes Object as a parameter, what should I do in a situation where the parameter is not the same type or a subtype as the LHS that equals had been called upon?
Option 1 - Return false because the objects are clearly not equals
Option 2 - Throw a casting exception because if the language actually supported variance (which would have been preferable), this would have been caught at compile time as an error; thus, detecting this error at runtime makes sense since a situation where another type is sent should have been illegal.

I vote for option 1. It is possible for two objects of different types to be equal -- for example, int and double, if first class objects, can validily be cast as each other and are comparable mathematically. Also, you may want to consider differing subclasses equal in some respects, yet neither may be able to be cast to the other (though they may be derived from the same parent).

Return false, because the objects are not equal.
I don't see how throwing a ClassCastException would be any better here.
There are contracts in interfaces such as Collection or List that actually depend on any object being able to check for equality with any other object.

It depends.
SomeClass obj1 = new SomeClass();
object other = (object)obj1;
return obj1.Equals(other); // should return "true", since they are really the same reference.
SomeClass obj1 = new SomeClass();
object other = new object();
return obj1.Equals(other); // should return "false", because they're different reference objects.
class SomeClass { }
class OtherClass { }
SomeClass obj1 = new SomeClass();
OtherClass obj2 = new OtherClass();
return obj1.Equals(obj2); // should return "false", because they're different reference objects.
If the types are two completely different types that don't inherit from one another, then there is no possible way they can be the same reference.
You shouldn't be throwing any type of casting exception because you're accepting the base object class as a parameter.

Hmmm.. I like Option 1 as well, for the following 4 reasons:
1) The objects were apparently not equal by whatever condition you used to check
2) Throwing ClassCastException requires a check for that exception every time you do a comparison, and I think that contributes to the code being less understandable or at least longer...
3) The class cast exception is merely a symptom of the problem, which is that the two objects were not equal, even at the type level.
4) As user "cbo" mentioned above, double/int being equal despite their types being different (4.0 == 4) and this applies to other types as well.
Disclaimer: I may be letting my Python ways colour a Java debate :)

Dr. Dobb's Java Q&A says the best practice is that they both are the same type. So I vote option 1.

Related

Why does Kotlin sortedWith() not just take a function

In this sample code sortedWith is used with the compare function. It appears that to specify the function one needs it to be inside a Comparator. This seems like an extra layer. Why does sortedWith not just take a function that is passed two T objects and returns an Int?
fun main(){println(get_list())}
fun get_list(): List<Int> {return arrayListOf(1, 5, 2)
.sortedWith(object:Comparator<Int>{override fun compare(l:Int,r:Int)=r-l})}
sortedWith reference page:
Being that sortedWith is only supported in the common libraries, I would reason that it is requiring a Comparable to more safely handle differences in how the target platforms handle comparisons of items.
Due to the receivers of both signatures being a sort of list (Not in the Kotlin type sense) you can expect that comparisons could be between different types between two iterations.
If you do not have a signature of compareTo between receiver type and input type, then it will not know how to safely convert between a Kotlin comparator versus say a Javascript comparison where
"" == false is True
"Hello World" == false is False
Though it's likely these kinds of specific language rules are taken into consideration in the language design, this is an example for primitives, where if we had runtime defined objects and other complex information, it could quickly break down.
If the Comparable was not used as an intermediary interface the expected comparisons might make sense in Kotlin, but when translated to the target platform might have unexpected consequences.
Long story short, it's a bit of an extra layer, to provide safety.

Assert.assertEquals junit parameters order

The order of the parameters for Assert.assertEquals method in JUnit is (expected, actual)
Although in another thread someone said that is for no reason, in one of my Java classes in Uni the professor mentioned a specific reason of that ordering, but I don't remember it.
Anybody can help me out with this?
Proper labeling in tools/failure results - The tools are following this order and some GUI tools will label which value is the expected value and which value is the actual value. At the very least, it will minimize confusion if the labels match the values; at worst, you spend time/effort tracking down the wrong issue trying to trace the source of the actual value that wasn't actually the actual value.
Consistency across assertEquals usage - If you aren't consistent in your order throughout your assertions, you can confuse future-you (or other future maintainer) if the values are swapped arbitrarily from case-to-case, again lending to potential confusion.
Consistent parameter ordering across assert methods - It may be reversible for assertEquals, but the order may matter for other assert* methods (in JUnit's built-ins and in other supporting code/libs). Better to be consistent across them all.
Changes in future - Finally, there may be a difference in a future implementation.
*Technical* - Its the expected value's equals method that is used:
There's one subtle difference after looking at the code. Many of the uses of assertEquals() will end up running through this method:
115 static public void assertEquals(String message, Object expected,
116 Object actual) {
117 if (expected == null && actual == null)
118 return;
119 if (expected != null && isEquals(expected, actual))
120 return;
...
128
129 private static boolean isEquals(Object expected, Object actual) {
130 return expected.equals(actual);
131 }
Its the equals method of the expected value that is used when both objects are non-null. One could argue that you know the class of the expected value (and thus know the behavior of the equals method of the expected value's class) but you may not necessarily know for certain the class of the actual value (which in theory could have a more permissive equals method). Therefore, you could get a different result if you swap the two arguments (i.e. the two different classes' equals methods are not reflexive of each other):
A contrived case would be an expected value of an ArrayList and an actual value that could return any type of Collection instance, possibly an ArrayList, but also possibly an instance of a custom Collection non-List class 'Foo' (i.e. Foo does not implement List). The ArrayList's equals method (actually its AbstractList.equals) specifies:
Returns true if and only if the specified object is also a list, both
lists have the same size, and all corresponding pairs of elements in
the two lists are equal.
Perhaps 'Foo' class's equals method is more permissive specifying:
Returns true if and only if the specified object is also a collection, both
collections have the same size, and both collections contain equal objects
but not necessarily in the same order.
By saying:
ArrayList expectArrayList = ...;
Collection actualCollectionPossiblyFoo = ...
Assert.assertEquals(expectedArrayList, actualCollectionPossiblyFoo)
you are saying you expect something equivalent to an ArrayList (according to ArrayList/AbstractList's definition of equals). This will fail if
actualCollectionPossiblyFoo is really of class Foo and thus not a List as
required by the ArrayList equals method.
However, this isn't the same as saying:
ArrayList expectedArrayList = ...;
Collection actualCollectionPossiblyFoo = ...;
Assert.assertEquals(actualCollectionPossiblyFoo, expectedArrayList);
because actualCollectionPossbilyFoo may be an instance of Foo and
Foo may consider itself and expectedArrayList to be equal according to
Foo class's equals method.
There is no specific reason. They could have ordered their parameters the other way. BTW, TestNG does it the other way.
For better readability and expressibility, I prefer using fluent assertions with fest-assert

What are better ways to create a method that takes many arguments? (10+?)

I was looking at some code of a fellow developer, and almost cried. In the method definition there are 12 arguments. From my experience..this isn't good. If it were me, I would have sent in an object of some sort.
Is there another / more preferred way to do this (in other words, what's the best way to fix this and explain why)?
public long Save (
String today,
String name,
String desc,
int ID,
String otherNm,
DateTime dt,
int status,
String periodID,
String otherDt,
String submittedDt
)
ignore my poor variable names - they are examples
It highly depends on the language.
In a language without compile-time typechecking (e.g. python, javascript, etc.) you should use keyword arguments (common in python: you can access them like a dictionary passed in as an argument) or objects/dictionaries you manually pass in as arguments (common in javascript).
However the "argument hell" you described is sometimes "the right way to do things" for certain languages with compile-time typechecking, because using objects will obfuscate the semantics from the typechecker. The solution then would be to use a better language with compile-time typechecking which allows pattern-matching of objects as arguments.
Yes, use objects. Also, the function is probably doing too much if it needs all of this information, so use smaller functions.
Use objects.
class User { ... }
User user = ...
Save(user);
It decision provides easy way for adding new parameters.
It depends on how complex the function is. If it does something non-trivial with each of those arguments, it should probably be split. If it just passes them through, they should probably be collected in an object. But if it just creates a row in a table, it's not really big deal. It's less of a deal if your language supports keyword arguments.
I imagine the issue you're experiencing is being able to look at the method call and know what argument is receiving what value. This is a pernicious problem in a language like Java, which lacks something like keyword arguments or JSON hashes to pass named arguments.
In this situation, the Builder pattern is a useful solution. It's more objects, three total, but leads to more comprehensible code for the problem you're describing. So the three objects in this case would be as such:
Thing: stateful entity, typically immutable (i.e. getters only)
ThingBuilder: factory class, creates a Thing entity and sets its values.
ThingDAO: not necessary for using the Builder pattern, but addresses your question.
Interaction
/*
ThingBuilder is a static inner class of Thing, where each of its
"set" method calls returns the ThingBuilder instance being worked with
while the final "build()" call returns the instantiated Thing instance.
*/
Thing thing = Thing.createBuilder().
.setToday("2012/04/01")
.setName("Example")
// ...etc...
.build();
// the Thing instance as get methods for each property
thing.getName();
// get your reference to thingDAO however it's done
thingDAO.save(thing);
The result is you get named arguments and an immutable instance.

Is it feasible to create a NullObject for every class? ( with a tool of course )

The NullObjectPattern is intended to be a "safe" ( neutral ) behavior.
The idea is create an object that don't do anything ( but doesn't throw NullPointerException either )
For instance the class defined as:
class Employee {
private String name;
private int age;
public String getName(){ return name; }
public int getAge() { return age; }
}
Would cause a NullPointerException in this code:
class Other {
Employee oscar;
String theName = oscar.getName(); // NPE
}
What the NOP says, is you can have an object like this:
class NullEmployee extends Employee {
public static final Employee instance = new NullEmployee();
public String getName(){ return ""; }
public int getAge() { return 0; }
}
And then use it as the default value.
Employee oscar = NullEmployee.instance;
The problem comes, when you need to repeat the code for every class you create, then a solution would be to have a tool to created it.
Would it be feasible/reasonable/useful to create such a tool or to use it ( if existed )?
Perhaps using AOP or DI the default value could be used automagically.
To me, the Null Object pattern feels like a placebo. A real object and a null object may have completely different meanings, but act very similar. Just like a placebo, the null object will trick you into believing there's nothing wrong, but something could be very wrong.
I think it's a good practice to fail early and fail often. In the end, you'll want to distinguish between a real object and a null object somewhere, and at that point it would be no different from checking against a null pointer.
From the Wikipedia article:
The advantage of this approach over a working default implementation is that a Null Object is very predictable and has no side effects: it does nothing.
It won't point out any problems either. Think of what will happen when a null object travels all the way through your application. Then, at some point, your application expects certain behavior from the object, which the null object implementation fails to deliver. At that point your application may crash or enter an invalid state. You'll have a very hard time tracing the origin of the null object. A null pointer would have thrown an exception right at the beginning, drawing your attention directly to the source of the problem.
The only example the Wikipedia article gives, is that of an empty collection instead of null. This is a very good practice, but a lousy example of the null object pattern, because it's dealing with a collection of objects, instead of a single instance.
In short, I'm sure it's feasible to create null object implementations for all your classes, but I strongly recommend against it.
I am not sure this is a good idea.
A "nullObject" may be useful and make perfect sense in some cases, but having this for every class is an overkill. Especially because this could potentially make some bug (or gaps in analysis) very hard to diagnose.
Also, what about 3rd part libraries that return new objects? Would you put some kind of "interface" in front of these so that in case they return null you will substitute an appopriate flavour of nullObject?
You mention that you are trying to automate this - wouldn't some cases require an actual design decision to return an appropriate value?
I.e., suppose you have an Image object, and it returns a "ImageType" (an Enumeration for .gif, .jpg etc.)
In this case, the ImageNullObject should return... "IMAGETYPE.GIF"? "IMAGETYPE.UNKNOWN"? Null?
I think you are just begging to push the error conditions down a layer.
When an application asks for an object, and it is null, then you need to deal with that condition, not just hope it is ok. If the object is null, and you try to use it, you will get errors, so why force all that error checking on the rest of the code?
I'd think it would be tricky to autogenerate functional null objects. (You could of course create shells that you then go and fill in the implementation itself).
As a quick example - what is the null functionality for a method that returns an int? Should it return -1, 0, or perhaps some other value? How about something that returns a String - again, is null or "" the correct choice? For methods returning some other class - if it's one of your own classes then presumably you could use the Null Object for that class, but how would you access it? Perhaps you could make every class you write implement some interface with an accessor for the null object, but is it worth it?
Even with methods that return void, it's not always the case that the null functionality is to simply return. Some classes, for example, might need to call a method on a parent/delegate object when they've done their own thing (which in this case would be a no-op) in order to preserve the invariants of the class.
So basically - even to implement "null" behaviour, you have to be able to infer what this behaviour is, and I expect this is far too advanced for a tool to do itself. Perhaps you could annotate all your methods with something like #NullReturns(-1), and have a tool pick these up and form the null object implementation, but even that won't cover every situation and you may as well write the object directly instead of writing all its functionality in annotations.
What I'd like to see would be for a compiler to allow one to define the behavior of a null object with a statically-defined type. For example, if 'Foo' is of class 'bar':
Class Bar
Dim Value as Integer
Function Boz() As Integer
Return Value
End Sub
Sub Nothing.Bar() As Integer
Return -9
End Sub
End Class
attempting to evaluate Foo.Bar() would yield Foo.Value if Foo is non-null, or else -9. One could achieve some such functionality using extension methods, but that seems a little icky.
Except for testing, I generally call this type of concept coding for Slop. It's the opposite of fail-fast, you are postponing any chance of locating a state you did not code for.
The main point here is why is it possible for your object to return a value that's not in the method's contract? When you designed and coded the method's contract, you either said it could or couldn't return null, right? So if you can return null, it's important. If you can't return null, it's important.
Also, If the object reference you are using can be null then that's a significant value and you shouldn't EVER be dipping into code that might access that object's methods.
On top of that, use final/constant/invariant variables every chance you get and (at least with OO languages, isolate your data behind a constructor that can insure correct state). If an immutable object correctly sets up it's variables, it's impossible for those variables to return invalid values.
Except for emergency patches and testing I honestly can't see any excuse for this kind of coding except "I don't understand the code and I think this isn't working right but I don't want to try to understand it"--which is not, IMO, a valid excuse for an engineer.

Why do constructors not return values?

Please tell me why the constructor does not return any value. I want a perfect technical reason to explain to my students why the constructor does not have any return type.
What actually happens with the constructor is that the runtime uses type data generated by the compiler to determine how much space is needed to store an object instance in memory, be it on the stack or on the heap.
This space includes all members variables and the vtbl. After this space is allocated, the constructor is called as an internal part of the instantiation and initialization process to initialize the contents of the fields.
Then, when the constructor exits, the runtime returns the newly-created instance. So the reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the runtime.
Its return value (if it actually has one when compiled down to machine code) is opaque to the user - therefore, you can't specify it.
Well, in a way it returns the instance that has just been constructed.
You even call it like this, for example is Java
Object o = new Something();
which looks just like calling a "regular" method with a return value
Object o = someMethod();
How is a constructor supposed to return a return value? The new operator returns the newly created instance. You do not call a ctor, newdoes it.
MyClass instance = new MyClass();
If the ctor would return a value, like so:
public int MyClass()
{
return 42;
}
Where would you receive the integer?
(I'm biased towards C++, so regarding other languages, take this with a grain of salt.)
Short answer: You don't want to have to explicitly check for success for every single object construction in your code.
Somewhat longer answer: In C++, constructors are called for dynamically as well as for globally and automatically allocated objects. In this code
void f()
{
std::string s;
}
there is no way for the constructor of s (std::string::string()) to return any value. Either it succeeds - then we can use the object, or it throws an exception - the we never get a chance to try to use it.
IMO, that's the way it should be.
A constructor is some method automatically called when you initialize a new instance of an object.
This method is there if you need to initialize your object to a given state and run few default methods.
Actually you can imagine the constructor always return the instance of the object created that would be a good image.
When you call a constructor the return value is the new object:
Point pt = new Point(1,2);
But within the constructor itself, you're not actually creating and returning the object; it's been created before your code starts, you're just setting up the initial values.
Point::Point(int x, int y) {
this->x = x;
this->y = y;
}
The lack of a return type reflects the fact that constructors are used differently than other functions. A return type of null, while technically accurate, doesn't reflect well the fact that the code is used as if it returns an object. However, any other return type would indicate that your code is supposed to return something at the end, which is also incorrect.
Constructor doesn’t return anything not even Void. Though some of the answers have mentioned that Constructor do return reference to the newly created object , which is not true. It’s the new operator that returns the object.
So Why constructor doesn’t return any value
Because its not supposed to return anything. The whole purpose of constructor is to initialize the current state of the object by setting the initial values.
So Why doesn’t it even return Void
This is actually a Design constraint which has been placed to distinguish it from methods. public void className() is perfectly legal in java but it denotes a method and not a constructor. To make the compiler understand that it’s a constructor , it requires a way to distinguish it.
all answers are biased towards C++/Java. there is no reason a constructor does not return a value other than the language design.
look at a constructor in a broader sense: it is a function which constructs a new object. you can write perfectly valid constructors in C:
typedef struct object object;
int object_create( object **this );
this is perfect OOP in C and the constructor returns value (this can also be called a factory, but the name depends on the intention).
however, in order to create an object automatically (to satisfy some type cast, or conversion for example), there have to be some rules defined. in C++, there is an argument-less constructor, which is inferred by the compiler if it is not defined.
the discussion is broader than what we think. Object Oriented Programming is a name which describes a way of thinking about programming. you can have OO in almost any language: all you need is structures and functions. mainstream languages like C++ and Java are so common that we think they define "the way". now look at the OO model in Ada: it is far from the model of C++ but is still OO. i am sure languages like Lisp have some other ways of doing OO.
One point that hasn't yet been discussed is that the constructor of class "foo" must be usable not only when creating instances of foo, but also when creating instances of classes derived from foo. In the absence of generics (which weren't available when Java, C++, or .net were designed) there would be no way for foo's constructor to return an object of any derived class. Therefore, what needs to happen is for the derived-class object to be created via some other means and then made available to foo's constructor (which will then be able to use the object in question as a foo when doing its initialization).
Even though the VM implementation of a constructor isn't to return any value, in practice it kind of does - the new object's reference. It would then be syntactically weird and / or confusing to be able to store one or both of the new object's reference and an additional return value in one statement.
So the reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the runtime. Its return value (if it actually has one when compiled down to machine code) is opaque to the user - therefore, you can't specify it.
Constructor is not directly called by the user's code. It's called by the memory allocation and object initialization code in the run time. Its value is not visible to the user.
In case of C#, the syntax for declaring object is :
classname objectname= new constructor();
According to this line, if we are using assignment operator(=) then it should return some value. But the main objective of a constructor is to assign values to variables, so when we use a new keyword it creates instance of that class, and constructor assigns values to the variable for that particular instance of object, so constructor returns assigned values for that objects's instance.
We can not call constructors independently. Instead they are automatically called whenever objects are created.
Ex:
MyDate md = new Mydate(22,12,2012);
In above example new will return a memory location which will be held by md, and programatically we can not return multiple values in single statements.
So constructors can not return anything.
From what I know about OO design methodologies, I would say the following:
1)By allowing a constructor to return a value, framework developer would allow the program to crash in an instant where the returned value is not handled. To keep the integrity of the program workflow, not allowing a return value from the initialization of an object is a valid decision. Instead, language designer would suggest/force the coders to use getter/setter - access methods.
2)Allowing the object to return a value on initialization also opens possible information leaks. Specially when there are multiple layer or access modifications applied to the variables/methods.
As you aware that when object is created constructor will be automatically called So now imagine that constructor is returning an int value. So code should like this...
Class ABC
{
int i;
public:
int ABC()
{
i=0;
return i;
}
.......
};
int main()
{
int k= ABC abc; //constructor is called so we have to store the value return by it
....
}
But as you aware that stament like int k= ABC abc; is not possible in any programming language. Hope you can understand.
i found it helpful
This confusion arises from the assumption that constructors are just like any other functions/methods defined by the class. NO, they are not.
Constructors are just part of the process of object creation. They are not called like other member functions.
I would be using Java as my language in the answer.
class SayHelloOnCreation {
public SayHelloOnCreation() {
System.out.println("Hello, Thanks For Creating me!");
}
}
class Test {
public static void main(String[]args) {
SayHelloOnCreation thing = new SayHelloOnCreation(); //This line here, produces an output - Hello, Thanks For Creating me!
}
}
Now let us see what is happening here. in java, we use the new keyword to create an instance of a class. And as you can see in the code, in the line, SayHelloOnCreation thing = new SayHelloOnCreation();, the expression after the assignment operator runs before assignment is done. So using the keyword new, we call the constructor of that class (SayHelloOnCreation()) and this constructor creates an object on the Java Heap. After the object is created, a reference to that object is assigned to the thing reference of type SayHelloOnCreation.
The point that I am trying to keep here is that if constructors were allowed to have a return type, Firstly the strongly typed nature of the language would be compromised (Remember I am speaking about Java here).
Secondly, an object of class SayHelloOnCreation is created here so by default I guess the constructor returns a reference of the same type, to avoid ClassCastException.
A method returns the value to its caller method, when called explicitly. Since, a constructor is not called explicitly, who will it return the value to. The sole purpose of a constructor is to initialize the member variables of a class.