Package Torello.Java.Additional
Class RetN
- java.lang.Object
-
- Torello.Java.Additional.RetN
-
public abstract class RetN extends java.lang.Object
This is a parent class of the 'Multiple Return Type' classes. (Ret2 ... Ret8
) This class provides some basic functionality to its descendants, namely:toString()
,hashCode()
andequals(RetN)
.
Hi-Lited Source-Code:- View Here: Torello/Java/Additional/RetN.java
- Open New Browser-Tab: Torello/Java/Additional/RetN.java
-
-
Method Summary
Convenience Getters for SubClasses Modifier and Type Method Object
get(int i)
<T> T
get(int i, Class<T> c)
<T> T
GET(int i)
Convert Fields to Object Array Modifier and Type Method Object[]
asArray()
Retrieve Number of Fields in this Class Modifier and Type Method abstract int
n()
Methods: class java.lang.Object Modifier and Type Method boolean
equals(RetN other)
int
hashCode()
String
toString()
-
-
-
Method Detail
-
n
public abstract int n()
All implementations of thisabstract
can indicate which of theRetN
instances they are, by returning the number of fields they hold using this method.- Returns:
- The number of fields contained by the class that is implementing
'this'
instance ofRetN
. So for example, an instance ofRet5
would produce'5'
, if this method were called; andRet3
would produce'3'
, and so on and so forth.
-
asArray
public final java.lang.Object[] asArray()
Retrieve the contents of the instance-descendant class, as an array.- Returns:
- Returns the instance fields
'a', 'b', 'c'
... of the class that has extended this class as anObject[]
array. - Code:
- Exact Method Body:
// All classes that inherit RetN implement the 'asArrayInternal()' method. // This method simply places the 'a', 'b', 'c' etc... fields into an Object[] array. if (this.objArr == null) this.objArr = asArrayInternal(); return this.objArr;
-
get
public final java.lang.Object get(int i)
This will return an instance ofObject
which represents theith
instance-field from whateverRetN
implementation this has been invoked.
If the implementing class wereRet5
, and'3'
were passed to parameter'i'
, then the value inRet5.c
would be returned.
If a call to'get'
is made fromRet2
, and'3'
were passed to'i'
, anIndexOutOfBoundsException
is thrown.
NOTE: This can make for easier typing if using the super-classRetN
in place of the actual multiple return-value classes themselves. However, remember, ifRetN
is used instead of the actual abstract-implementation ('Ret5'
, for instance) you will need cast the fields that you wish to use, eventually!
Example:
// This line makes for longer typing, but DOES NOT REQUIRE A CAST TO RETRIEVE FIELDS. Ret5<String, String, Integer, String[], Integer> r5 = some_function_returns5(); String neededStrField = r5.c; // If the Ret5 super-class RetN is used instead, YOU HAVE TO CAST THE FIELDS TO RETRIEVE THEM // The above two lines of code may be replaced by: RetN rn = some_function_returns5(); String neededStrField = rn.get(3, String.class); // Passing '3' gets field Ret5.c // **OR** @SuppressWarnings("unchecked") String neededStrField = (String) rn.get(3);
- Parameters:
i
- This specifies which field of the implementingRetN
is being requested.
IMPORTANT: Unlike a Java array, when a'1'
is passed to this parameter, it is requesting the first field in theRetN
. Passing a value of '0' shall cause anIndexOutOfBoundsException
throw.- Returns:
- This returns the
ith
field of this class. - Throws:
java.lang.IndexOutOfBoundsException
- if'i'
is zero or negative, or greater than the value of'N'
for whicheverRetN
class is being used. If'this'
is an instance ofRet5
, then a value of 6 or greater will cause this exception to throw.- See Also:
asArray()
,get(int, Class)
,GET(int)
- Code:
- Exact Method Body:
Object[] objArr = asArray(); if (i < 1) throw new IndexOutOfBoundsException( "You have passed " + i + " to parameter i. This number must be " + ((objArr.length > 1) ? ("between 1 and " + objArr.length) : "must be exactly 1.") ); else if (i > objArr.length) throw new IndexOutOfBoundsException( "You have requested the " + StringParse.ordinalIndicator(i) + " field of " + "this class instance-fields, but unfortunately there " + ((objArr.length > 1) ? ("are only " + objArr.length + " fields.") : ("is only 1 field.") ) ); return objArr[i-1]; // minus one, arrays start at index 0.
-
get
public final <T> T get(int i, java.lang.Class<T> c)
This provides a quick way to cast the field to the requested class. This may be quicker typing than using an actual cast, because it will not generate a compiler warning about unchecked casts. If the cast fails, it will throw the usualClassCastException
.- Parameters:
i
- This specifies which field of the implementingRetN
is being requested.
IMPORTANT: Unlike a Java array, when a'1'
is passed to this parameter, it is requesting the first field in theRetN
. Passing a value of '0' shall case anIndexOutOfBoundsException
exception.- Returns:
- This returns the
ith
field of this class. - Throws:
java.lang.IndexOutOfBoundsException
- if'i'
is zero or negative, or greater than the value of'N'
for whicheverRetN
class is being used. If'this'
is an instance ofRet5
, then a value of 6 or greater will cause this exception to throw.java.lang.ClassCastException
- If the field cannot be cast to the class provided.- See Also:
get(int)
,GET(int)
- Code:
- Exact Method Body:
return c.cast(get(i));
-
GET
public final <T> T GET(int i)
This is more magic with Java's Type-Inferencing being applied to a Generic-Cast. Note that this method works a lot like (but not identical to) the later Java'var'
syntax. Here, Java's Type-Inference Mechanism (inside the compile-time, not run-time, logic) will cast the result of this method to whatever type is on the left hand-side of the assignment.
NOTE: The Java Compiler will output a Compile-Time Error if it appears that it cannot infer type-parameter'T'
.
ALSO: This method will throw a Run-Time Exception if the cast fails (a'ClassCastException'
)- Type Parameters:
T
- This Type-Parameter is inferred by whatever assignment is taking place, or however the result of this method is being applied, programatically. More can be read about Java's Compile-Time Type-Inferencing Mechanism on the Oracle Website.- Parameters:
i
- This specifies which field of the implementingRetN
is being requested.
IMPORTANT: Unlike a Java array, when a'1'
is passed to this parameter, it is requesting the first field in theRetN
. Passing a value of '0' shall case anIndexOutOfBoundsException
exception.- Returns:
- This returns the
ith
field of this class. - Throws:
java.lang.IndexOutOfBoundsException
- if'i'
is zero or negative, or greater than the value of'N'
for whicheverRetN
class is being used. If'this'
is an instance ofRet5
, then a value of 6 or greater will cause this exception to throw.java.lang.ClassCastException
- If theith
field of this class cannot be cast to the type that is inferred for Type-Parameter'T'
.- Code:
- Exact Method Body:
return (T) get(i);
-
equals
public boolean equals(RetN other)
Compares'this'
with another instance ofRetN
.- Parameters:
other
- Another instance ofRet8
.- Returns:
- If
'this'
instance ofRet8
is equal to the'other'
instance ofRet8
. - Code:
- Exact Method Body:
if (this == other) return true; Object[] theseFields = asArray(); Object[] thoseFields = other.asArray(); // This should never happen, because the RetN that calls this only accepts a RetN // of the same type. Leave this here, anyway, you will forget that, and try to type // this again. if (theseFields.length != thoseFields.length) return false; for (int i=0; i < theseFields.length; i++) if (theseFields[i] == thoseFields[i]) continue; else if ( ((theseFields[i] != null) && (thoseFields[i] != null)) && (theseFields[i].getClass() == thoseFields[i].getClass()) && theseFields[i].equals(thoseFields[i]) ) continue; else return false; return true;
-
hashCode
public int hashCode()
Builds a hash-code to fulfill Java'sjava.lang.Object
requirement. This variant of a hash function simply computes a hashcode for the first two non-null fields of this instance, and returns their sum.
If there aren't at least two non-null fields in thisRetN
instance, then the hashcode for however many have been computed (READ: either 0, or 1) is returned.- Overrides:
hashCode
in classjava.lang.Object
- Returns:
- a hash-code that may be used for sets and maps like
java.util.Hashtable
andjava.util.HashSet
. - Code:
- Exact Method Body:
// This is the value returned. int hashCode = 0; int count = 0; for (Object field : asArray()) if (field != null) { hashCode += field.hashCode(); // Once two Hash Code's have been computed return the 'SUM' of them. if (++count == 2) return hashCode; } return hashCode;
-
toString
public java.lang.String toString()
Converts this instance of the implementingRetN
to aString
.- Overrides:
toString
in classjava.lang.Object
- Returns:
- This instance-object as a
String
. - Code:
- Exact Method Body:
// When a field is set to null, it is more difficult to retrieve the type/class of that // field. The class is printed as part of the output of the 'toString' method. It does // make the string look nicer, and likely will help the user. // // NOTE: If none of the fields in whatever instance 'this' is a instance of, then variable // 'thisClass' is never actually used. Class thisClass = this.getClass(); // All RetN implementations return their fields as an array. This array is only created // once (in a transietn field), defined above. Object[] fields = asArray(); // whatever 'RetN' implentation this instance is, this is actually just the value of 'N' int n = n(); // Tells the output-printing mechanism when/if one of the fields is an array. boolean[] isArray = new boolean[n]; // These will hold the "Simple Name's" of each class/type in the previous array. String[] types = new String[n]; // The fields are named 'a ... e', unless N is 6, 7, or 8. In that case the fields are // named 'a1 ... h8' String[] FIELD_NAMES = (n < 6) ? fieldNames2To5 : fieldNames6To8; // This will hold the returned java.lang.String that is provided by this method call. StringBuilder sb = new StringBuilder(); // Simple Loop Variables int i=0, maxLen=0; // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // Loop merely retrieves the TYPE/CLASS of each field as a STRING (and if it is an array) // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** for (Object field : fields) { // If the field is non-null, retrieving the class is easy, otherwise, it isn't-possible // because of GENERIC-ERASURE if (field != null) { Class c = field.getClass(); types[i] = c.getSimpleName(); isArray[i] = c.isArray(); } else { types[i] = "<GENERIC-ERASURE>"; // Smoke 'em if you got 'em isArray[i] = false; // DUMMY-VALUE } // These String's are pretty-printed with right-space-pad. This computes the padding. if (types[i].length() > maxLen) maxLen = types[i].length(); i++; } // Formatting: the '+2' adds two space-characters to the output. These spaces occur // *AFTER* the Type/Class is printed to the output. maxLen += 2; i=0; for (Object field : fields) { // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // This print's the NAME & TYPE of the Field - For Example: "Ret6.a1: String" // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** String line = "Ret" + n + "." + FIELD_NAMES[i] + ": " + StringParse.rightSpacePad(types[i], maxLen); sb.append(line); // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // This simply prints the VALUE of the Field. For arrays, "extra-care is provided" // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** if (field != null) { String s = isArray[i] ? toArrayString(field, types[i]) : field.toString(); if (s.indexOf('\n') != -1) sb.append('\n' + StrIndent.indent(s, 4)); else if (line.length() + s.length() > 70) sb.append('\n' + StrIndent.indent(s, 4)); else sb.append(s); } else sb.append("null"); sb.append('\n'); i++; } return sb.toString();
-
-