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.
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.