Java constructor design - java

I was reading an open-source code, and there was a constructor designed like this:
public class FeatureSequence2FeatureVector extends Pipe implements Serializable
{
boolean binary;
public FeatureSequence2FeatureVector (boolean binary)
{
this.binary = binary;
}
public FeatureSequence2FeatureVector ()
{
this (false);
}
}
This may be just a trivial preference matter, but what I would do is like this:
public class FeatureSequence2FeatureVector extends Pipe implements Serializable
{
boolean binary = false;
public FeatureSequence2FeatureVector (boolean binary)
{
this.binary = binary;
}
public FeatureSequence2FeatureVector ()
{
}
}
Is there any possible negative outcome by assigning an initial value for class variables?
Would the two ways be almost equally preferred?

These two ways are not equally preferred.
The original way makes sure that all initialization goes through a primary constructor. The second way allows different paths for initializing an object.
In your example it's pretty trivial. But with the second way one constructor could be modified to do something different from how the other constructor did things, whereupon how your objects are initialized depends on which constructor was chosen.
This question shows a situation where allowing different paths caused trouble.

One reason I've seen developers do this is for maintainability and future-proofing.
Let's break it down into a different application:
public void foo() {
this.foo(1);
}
public void foo(int a) {
this.foo(a, 2, 3);
}
public void foo(int a, int b, int c) {
// ...
}
foo is assumed to do the exact, or a similar, operation - regardless of the overload. However, what if that functionality were to change? In your example, you'd have to change the functionality for both versions, whereas in the above example, only foo(int, int, int) would have to be changed.
Future-proofing is something that is taken into account in the design of an API, and the above design pattern is adopted frequently due to the ability to maintain one block of code versus 2 or 3 (or however many overloads you have).
Constructors are no different, other than that they are invoked with this(...).

Related

Can Java generics be parameterized with values instead of types?

Assume I want to define types that are similar in structure, but differ in a parameter that could be an integer or could be something else.
Is it possible in Java to define a family of classes parameterized by an integer or even an arbitrary object?
Consider the following pseudocode (which does not compile):
/**
* String of a certain length n and a method to reduce to length n-1
*/
public class StringN<int n> {
private String str;
public StringN( String str) {
if(str.length() != n) {
throw new IllegalArgumentException("string is not of required length!");
}
this.str = str;
}
public StringN<n-1> reduce() {
return new StringN<n-1>(s.substring(0, s.length() - 1));
}
#Override
public String toString() {
return str;
}
}
Other even more natural examples that come to my mind are tensor-products in math, so where to put the parameter 'n', if one wants to define e.g. the space R^n as a Java class or in functional programming the 'arity' of a Function<>-space. So how to define a family of classes with different arity, parameterized by n?
If this is not possible in Java, does this concept exist in other more functional languages and what is the proper name for it? (like maybe 'parameterized class'?)
Edit: as a reaction to comments, the last part was just to know the general name of such a concept, not to make a detour to other languages.
Alas, Java requires type parameters to be types (actually, it even requires them to be reference types), and since all integers are of the same type, you not get the compiler to distinguish generics depending on the value of an integer.
The usual workaround is to declare a separate type for each possible (or needed) value. To share structure, you can use an abstract base class. And if the base class needs any concrete types, the subclasses can pass them as type parameters:
abstract class StringN<S extends StringN<S,P>, P extends StringN<P,?>>
implements Comparable<S> {
final String value;
protected StringN(String value, int n) {
if (value.length() != n) {
throw new IllegalArgumentException(value);
}
this.value = value;
}
#Override
public int compareTo(S o) {
return value.compareTo(o.value);
}
abstract P newP(String value);
public P removeLast() {
return newP(value.substring(0, value.length() - 1));
}
}
class String0 extends StringN<String0, String0> {
protected String0(String value) {
super(value, 0);
}
#Override
String0 newP(String value) {
throw new UnsupportedOperationException();
}
}
class String1 extends StringN<String1, String0> {
protected String1(String value) {
super(value, 1);
}
#Override
String0 newP(String value) {
return new String0(value);
}
}
class String2 extends StringN<String2, String1> {
protected String2(String value) {
super(value, 2);
}
#Override
String1 newP(String value) {
return new String1(value);
}
}
public class Test {
public static void main(String[] args) {
String2 s2 = new String2("hi");
String1 s1 = s2.removeLast();
s1.compareTo(s2); // compilation error: The method compareTo(String1) is not applicable for the arguments (String2)
}
}
As you can see, as long as the set of values is finite and known up front, you can even teach the compiler to count :-)
However, it gets rather unwieldy and hard to understand, which is why such workarounds are rarely used.
Yours is an interesting question, but I think you went too far in assuming that the solution to your need is necessarily a parametrized class.
Parametrized classes are composition of data types, not values.
Since you do not require the compile to enforce any additional static type checkings on your code, I think a programmatic solution would be enough:
First step: Move your pseudo-parameter "int n" to a final variable:
public class StringN {
private final int n;
private String str;
public StringN( String str) {
if(str.length() != n) {
throw new IllegalArgumentException("string is not of required length!");
}
this.str = str;
}
public StringN reduce() {
return new StringN(s.substring(0, s.length() - 1));
}
#Override
public String toString() {
return str;
}
}
Of course, this do not compile yet. You must initialize the n variable on every constructor (declarations and callings).
If you feel uncomfortable with the fact of exposing the parameter n as part of the public constructors calling, that can be solved restricting the constructors to package access, and bringing the construction responsibility to a new Factory class, which must be the only public way to create StringN objects.
public StringNFactory
{
private final int n;
public StringNFactory(int n)
{
this.n=n;
}
public StringN create(String s)
{
return new StringN(this.n, s);
}
}
As the name suggests, a "type parameter" is a type. Not 'a length of a string'.
To be specific: One can imagine the concept of the type fixed length string, and one can imagine this concept has a parameter, whose type is int; one could have FixedString<5> myID = "HELLO"; and that would compile, but FixedString<5> myID = "GOODBYE"; would be an error, hopefully a compile-time one.
Java does not support this concept whatsoever. If that's what you're looking for, hack it together; you can of course make this work with code, but it means all the errors and checking occurs at runtime, nothing special would occur at compile time.
Instead, generics are to give types the ability to parameterize themselves, but only with a type. If you want to convey the notion of 'A List... but not just any list, nono, a list that stores Strings' - you can do that, that's what generics are for. That concept applies only to types and not to anything else though (such as lengths).
Furthermore, javac will be taking care of applying the parameter. So you can't hack it together by making some faux hierarchy such as:
public interface ListSize {}
public interface ListIsSizeOne implements ListSize {}
public interface ListIsSizeTwo implements ListSize {}
public interface ListIsSizeThree implements ListSize {}
and then having a FixedSizeList<T extends ListSize> so that someone can declare: FixedSizeList<ListIsSizeTwo> list = List.of(a, b);.
The reason that can't work is: You can't tell javac what to do, it's not a pluggable system. Java 'knows' how to apply type bounds. It wouldn't know how to enforce size limits, so you can't do this.
I'm answering the question myself, because the useful information is distributed over several comments/answers. I made this a community-wiki answer, so that I don't earn reputation for suggestions of others.
The feature I'm looking for is apparently a particular case of so-called dependent-typing (thanks #DylanSp). Also template parameters of C++ (with the parameter not being a type) are an example of such a feature (thanks #Turing85). All answers agree that this feature unfortunately does not exist in Java, neither within the syntax of Java Generics (#rzwitserloot and others pointed out that Java specification allows only reference types in the diamond <>), nor any other syntax.
One certainly can manually define types in Java for each particular n. So for my example in my question, one can define classes String1, String2, String3, ..., but only finitely many ones. In order to make the definition of each particular type as simple as possible, one can use an approach with an abstract base class that is shared by all of these classes, see #meriton's nice suggestion.
Not what I was thinking of, but with finitely many cases also a code generator (mentioned by #Hulk) should be an option. If I understand correctly that's also what #MC Emperor had in mind when mentioning annotations.
However, if one really wants to stick to infinitely many classes (that's what I want), the only way out seems to be, to make the counter n a member of a single class and just think of them being different types. At compiler-level, there won't be any type-checking, so one has to implement type-safety oneself. The suggestion with the factory made by #Little Santi would be a way to bring more structure into this approach.

How can my method accept any type of Number, as a method argument? (Java generics)

My CustomNumber class extends the Number class (implements all the method, but not listed here). The class has a division method, which should work as the following: I can give to it any type of Number argument, and always get a the calculation without precision loss. That is why I'm thinking about double values. But in this case, I can't call this method with anything else, but Double Objects. How can I make this method, any maybe the whole class 100% generic?
public class CustomNumber<T> extends java.lang.Number {
java.lang.Number value;
public CustomNumber(java.lang.Number value) {
this.value = value;
}
public static CustomNumber<Double> division(Number a, Number b) {
return new CustomNumber<>(a.doubleValue() / b.doubleValue());
}
}
In this respect, Java is extremely annoying.
They dogmatically disallowed operator overloading (although Scala has it), so you are compelled to code / into a method called divide or similar, and so on.
For more specifics see how the arbitrary precision libraries such as BigInteger are implemented, and base your solution from that.
One a plus point in Java, you might get away with using BigDecimal and doing away with your idea entirely. Although the code you end up with when performing complex mathematical operations with it is practically unreadable. (For this reason I resort to using C++ with a JNI).
If this was what you were trying, it doesn’t work:
CustomNumber<Integer> quotient = division(5, 3);
We get “Type mismatch: cannot convert from CustomNumber<Double> to CustomNumber<Integer>”. For an obvious reason. Even though the numbers you tried to divide were autoboxed into Integer.
The straightforward solution is to drop the generics completely:
public class CustomNumber extends java.lang.Number {
// ...
public static CustomNumber division(Number a, Number b) {
return new CustomNumber(a.doubleValue() / b.doubleValue());
}
}
Now we have no problem doing:
CustomNumber quotient = division(5, 3);
System.out.println(quotient);
With an appropriate toString method in your class this should print:
1.6666666666666667
java.lang.Number offers very few methods. Division, for instance, doesn't really do the same thing for each type. 1.0d/2.0d is 0.5d but 1/2 is 0. So you're going have to decide which you're doing. Also note the double does not exactly represent long or, say, BigInteger.
To map various forms of numbers to your common interpretation, you'll need an adapter layer. There may be ore than one way to map a numeric type.
public interface CustomNumber<THIS extends CustomNumber<THIS>> {
THIS divide(THIS other);
}
public final class LongNumber extends CustomNumber<LongNumber> {
// (Note, you don't actually need to overload this,
// but it does prevent the likes of LongNumber.of(aDouble).)
public static LongNumber of(Long value) {
return new LongNumber(value);
}
public static LongNumber of(AtomicLong value) {
return new LongNumber(value);
}
private final Number value;
private LongNumber(Number value) {
this.value = value;
}
#Override public LongNumber divide(LongNumber other) {
return this.longValue() / other.longValue();
}
}
You might want to have an adapter for the same types that deal with, say, bankers' rounding. I don't want to even think about how to implement that. Or full on saturated arithmetic. So here's is a sign preserving alternative implementation (still does division by zero):
#Override public SignPreservingLongNumber divide(
SignPreservingLongNumber other
) {
long dividend = this.longValue();
long divisor = other.longValue();
return (
dividend == Long.MIN_VALUE &&
divisor == -1
) ? Long.MAX_VALUE : dividend/divisor;
}

Java "Closures" comparison between Local and Anonymous Class

I have done some searching on the difference in implementing a closure using an anonymous class and a local class. I am trying to figure out all the differences between the two so I know which method is better in which situations.
Correct me if I am wrong:
The anonymous class has a class instance and object instance created each time a new instance is created.
The local class has only an object instance create each time a new instance is created.
Therefore, is there ever a time or place where I should use an anonymous class over a local class?
EDIT: It appears there is no real difference between the two, just depends on style and if you want to reuse the class.
To clarify what I mean here is an example of what I am talking about:
public class ClosureExample {
interface Function {
void func(int value);
}
public static void main(final String[] args) {
final Function local1 = localClassClosure("Local1");
final Function local2 = localClassClosure("Local2");
final Function anonymous1 = anonymousClassClosure("Annonymous1");
final Function anonymous2 = anonymousClassClosure("Annonymous2");
for (int i = 0; i < 3; i++) {
local1.func(i);
local2.func(i);
anonymous1.func(i);
anonymous2.func(i);
}
}
private static Function localClassClosure(final String text) {
// Local class name is irrelevant in this example
class _ implements Function {
#Override public void func(final int value) {
System.out.println(text + ":" + value);
}
}
return new _();
}
private static Function anonymousClassClosure(final String text) {
return new Function() {
#Override public void func(final int value) {
System.out.println(text + ":" + value);
}
};
}
}
Hopefully, someone can explain in detail this subtle difference and which method should be used in which situations.
This piqued my interest, and I broke out JD-GUI to look at the decompiled classes. There is actually no difference at all between the two anonymous inner classes after compilation:
localClass:
class ClosureExample$1t implements ClosureExample.Function{
ClosureExample$1t(String paramString){
}
public void func(int value){
System.out.println(this.val$text + ":" + value);
}
}
anonymousClass:
class ClosureExample$1 implements ClosureExample.Function{
ClosureExample$1(String paramString){
}
public void func(int value){
System.out.println(this.val$text + ":" + value);
}
}
Both methods are valid ways of implementing an anonymous inner class, and they seem to do the exact same thing.
EDIT: I renamed the _ class to t
I am pretty sure there is nothing like object instance, just class instance .
So yes an object is created for both local and anonymous types..
The difference however is you can't reuse the anonymous class (except through the way you used it in your method - which works but not really maintainable), so you use it when whatever you are doing is a one off thing. For example with event listeners.
I would prefer named types to anonymous types though.
You might find this useful
EDIT:
You will find my question here useful.
Just a note about this:
Therefore, is there ever a time or place where I should use an anonymous class over a local class?
If you need to quickly setup an event listener [e.g. a KeyListener] inside a component, you can do like this:
addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent ke){ ... }
// further implementation here
});
Though it won't be reusable at all.
The local class object is faster at initialization (because the class is already in memory at startup)
The anonymous class object less memory consuming (because of the lazy evaluation)
Notice : Because java is not a real functional language. Anonymous classes will be pre-evaluated and even stored in class files. So really there wont be much difference.
In a functional language, like scheme :
(define inc (lambda (a) (lambda () (+ 1 a))))
(display ((inc 5)))
The function (lambda () (+ 1 a)) will be actually recreated at each anonymous call like ((inc 5)). This is the concept behind anonymous classes.
As opposed to:
(define inc (lambda (a) (+ 1 a)))
(display (inc 5))
Where (lambda (a) (+ 1 a)) will be stored in memory at compile time, and the call to (inc 5) will only reference it. This is the concept behind local classes.

Java subclass does not recognise its generic superclass

I need help with a problem I have with generics in Java. I'm writing this Computer algebra system, where the user enters a math expression and the system works with it in different ways (expand it, simplify it etc). It worked fine for expressions containing natural numbers, and I wanted to expand it to work with mathematical sets as well. Instead of +, you would have the intersection operator, etc.
At first, I started recording everything for the sets, but then I realized this was probably not good and started using generics.
Instead of having one parse tree like MathExpr and one like SetExpr, I thought I could just have a generic Expression<T> and build a base class Number and a base class Set.
To try to clarify, I want a mathematical expression like (2 * a) + (3 + 2) to be an instance of a class Expression<Number> and a set expression like (A ∪ B) ∩ C to be an instance of Expression<Set>. I can then perform different operations on this, like calculate the depth etc.
The + operation is implemented as one class, the * as one class etc. Both these classes are subclasses of an abstract class called TwoExpr which in turn is a subclass of the abstract class Expr. This is how I have done it now and everything works fine.
When I wanted to change my code I made my Expr class generic. That is Expr<T>. I also changed TwoExpr to TwoExpr<T> and created a base class Number.
The problem is, now I can't seem to instantiate objects of the type Sum<Number>.
I get a "Type mismatch: cannot convert from Sum to Expr<Number>" error. But Sum is a subclass of TwoExpr<Number>, which in turn is a subclass of Expr<Number>. As you may realize, I can't make the class Sum generic and call it Sum<Number>, because all arithmetic operations don't have analogues for sets.
I have always been able to create objects like
Expr zero= new Leaf(0);
Variable a = new Variable("a");
Expr aPlusZero = new Sum(a, zero);
When I changed to generics, the same code looks like this:
Expr<Number> zero= new Leaf<Number>(new Number(0)); //works fine
Variable<Number> a = new Variable<Number>("a"); //works fine
Expr<Number> APlusZero=new Sum(a,zero); //gives a "Type mismatch:
//cannot convert from Sum to Expr<Number>" error
How come it doesn't recognize that Sum(a,zero) is a subclass of Expr<Number>, when it says in the declaration of Sum
public class Sum extends TwoExpr<Number> {
public Sum(Expr<Number> a, Expr<Number> b) {
super(a, b);
}
...
}
and in the declaration of TwoExpr
public abstract class TwoExpr<T> extends Expr<T> {
protected Expr<T> a;
protected Expr<T> b;
public TwoExpr(Expr<T> a, Expr<T> b) {
this.a=a;
this.b=b;
}
...
}
I know that Lizkows substitution principle doesn’t apply for generic arguments. But Number isn’t a subclass of anything (except Object) and don't have any subclasses.
I hope I've been fairly clear about what I'm trying to do and what problem I have. Does anybody have any idea how to solve it? Please tell me if anything was unclear in the above or if you want more code.
Thanks in advance.
Mattias
I think your problem is in the classes you did not show, I tried the following and it works:
Expr<Number> zero= new Expr<Number>();
Expr<Number> a= new Expr<Number>();
Expr<Number> APlusZero=new Sum(a,zero);
Might it be that Variable is not an Expr?
UPDATE:
I played a little creating Variable and Leaf as I imagine them and it all works:
public class Number {
public Number(int i){}
}
public class Variable<T> extends Expr<T> {
public Variable(String s){}
}
public class Leaf<T> extends Expr<T> {
public Leaf(T t) {
super();
}
}
public class Expr<T> {
}
public class TwoExpr<T> extends Expr<T> {
public TwoExpr(Expr<T> a, Expr<T> b) {
}
}
public class Sum extends TwoExpr<Number> {
public Sum(Expr<Number> a, Expr<Number> b) {
super(a, b);
}
}
public class AllTogether {
public static void main(String[] args) {
Expr<Number> zero= new Leaf<Number>(new Number(0));
Variable<Number> a = new Variable<Number>("a");
Expr<Number> APlusZero=new Sum(a,zero);
}
}
If you take the extends Expr from Variable it does give the error you experience, might it be this the cause?
Maybe try to debug it:
Object = new Sum(a,zero);
System.out.println(o.getClass().getGenericSuperclass());
Furthermore maybe is a better solution for your system.
Sum does not import Types.Number. So it's not Expr<Types.Number> but Expr<java.lang.Number>. I would assume this would give a compilation error not only on the assignment but also on the construction of new Sum(vA, zero), but maybe the compiler sees the other error first.

Using "this" with methods (in Java)

what about using "this" with methods in Java? Is it optional or there are situations when one needs to use it obligatory?
The only situation I have encountered is when in the class you invoke a method within a method. But it is optional. Here is a silly example just to show what I mean:
public class Test {
String s;
private String hey() {
return s;
}
public String getS(){
String sm = this.hey();
// here I could just write hey(); without this
return sm;
}
}
Three obvious situations where you need it:
Calling another constructor in the same class as the first part of your constructor
Differentiating between a local variable and an instance variable (whether in the constructor or any other method)
Passing a reference to the current object to another method
Here's an example of all three:
public class Test
{
int x;
public Test(int x)
{
this.x = x;
}
public Test()
{
this(10);
}
public void foo()
{
Helper.doSomethingWith(this);
}
public void setX(int x)
{
this.x = x;
}
}
I believe there are also some weird situations using inner classes where you need super.this.x but they should be avoided as hugely obscure, IMO :)
EDIT: I can't think of any examples why you'd want it for a straight this.foo() method call.
EDIT: saua contributed this on the matter of obscure inner class examples:
I think the obscure case is: OuterClass.this.foo() when accessing foo() of the outer
class from the code in an Inner class that has a foo() method as well.
I use "this" to clarify code, often as a hint that I'm calling an instance method rather than accessing a class-level method or a field.
But no. Unless disambiguation is required due to scope naming collision, you don't actually need "this."
For most general programing, the this keyword is optional and generally used to avoid confusion. However, there are a few places where it is needed.
class Foo {
int val;
public Foo(int val) {
this(val, 0); //this MUST be here to refer to another constructor
}
public Foo(int val, int another) {
val = val; //this will work, but it generally not recommended.
this.val = val; //both are the same, but this is more useful.
method1(); //in a Foo instance, it will refer to this.method1()
this.method1(); //but in a Foo2 instance, you must use this to do the same
}
public void method1() {}
}
class Foo2 extends Foo {
public Foo2(int val) {
this(val); //this will refer to the other Foo2 constructor
}
public Foo2(int val, int another) {
super(val, another);
super.method1(); //this will refer to Foo.method1()
}
#Override
public void method1() {}//overridden method
}
These are not all the cases, but some of the more general ones. I hope this helps you better understand the this and super keywords and how/when to use them.
The only reason to prepend this in front of a method invocation is to indicate that you're calling a non-static method. I can't think of any other valid reason to do this (correct me I'm wrong). I don't recommend this convention as it doesn't add much value. If not applied consistently then it could be misleading (as a this-less method invocation could still be a non-static method). How often does one care if the method being invoked is static or not? Furthermore, most IDEs will highlight static methods differently.
I have heard of conventions where this indicates calling the subclass's method while an absence of this is calling the super class's method. But this is just silly as the convention could be the other way around.
Edit: As mmyers points out (see comment), this works with static methods. With that, I see absolutely no reason to prepend with this as it doesn't make any difference.
The only time it is really required is when you have a parameter to a method with the same name as a member variable. Personally, I try to always use it to make the scope of the variable/method explicit. For example you could have a static method or an instance method. When reading the code it can be helpful to know which is which.
Not an answer (so feel free to vote it down), but I couldn't fit this into a comment where someone was asking.
A lot of people use "this.x" to visually differentiate instance variables from local variables and parameters.
So they would do this:
private int sum;
public int storeSquare (int b) {
int c=b*b;
this.sum+=c; // Makes sum "pop" I guess
return c;
}
Personally I think it's a bad habit: any usable editor will put instance and local variables in a different color for you reliably--it doesn't require any human-fallible patterns.
Doing it with "this." is only 50% safe. Sure the compiler will catch it if you try to put this.x when x is a local variable, but there is nothing that is going to stop you from "Forgetting" to tag an instance variable with this., and if you forget to tag just one (or if someone else works on your code) and you are relying on the pattern, then the pattern may be more damaging than good
Personally I'm fairly sure the pattern stems from programmers (rightful) discomfort with the fact that in this case:
public void setMe(int me) {
this.me=me;
}
the fact that you need "this." in front of the me is determined by the name of the parameter--I agree it just feels sloppy. You want to be consistent--if you need this. in front of the me there, why not always use it?
Although I understand the discomfort, typing this. every single place that an instance variable is used is just pedantic, pointless, ugly and unreliable. If it really bothers you and you absolutely need to use a pattern to solve it, try the habit of putting "p" in front of your parameters. As a side effect, it should even make it more constant because the parameter case will now match the method case..
public void setMe( int pMe)
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html
You absolutely need this if your method needs to return the object's instance.
public class StringBuildable {
public StringBuildable append(String text) {
// Code to insert the string -- previously this.internalAppend(text);
return this;
}
}
This allows you to chain methods together in the following fashion:
String string = new StringBuildable()
.append("hello")
.append(' ')
.append.("World")
.toString()
;

Categories