Reputation: 63231
I have the unfortunate task of converting a networking library that I wrote couple years back from scala
to java
due to lack of offshore scala
resources.
One of the tricker areas : converting the package
object and its type aliases
and case classes
. Here is an excerpt:
package object xfer {
type RawData = Array[Byte]
type DataPtr = String
type PackedData = RawData
// type PackedData = (DataPtr, RawData, RawData)
// type UnpackedData = (DataPtr, Any, RawData)
type UnpackedData = Any
case class TaggedEntry(tag: String, data: Array[Byte])
case class TypedEntry[T](tag: String, t: T)
case class XferWriteParams(tag: String, config: XferConfig, data: RawData, md5: RawData) {
override def toString: DataPtr = s"XferWriteParams: config=$config datalen=${data.length}} md5len=${md5.length}}"
}
As an example the RawData
has 32 usages. I suppose that one approach could be to do simple Find/Replace of all 32 instances with byte[]
: but is there a more elegant way?
For the case class
'es .. I'm leery of creating another few top level files in this package for each of them - and likewise another few top level files in each of a dozen other packages .. but is there any alternative?
Upvotes: 2
Views: 55
Reputation: 44967
ADT-esque trait-case-class clusters like
trait T
case class C1 extends T
case class C2 extends T
could be converted to an abstract base class T
, with nested static classes C1
, C2
:
abstract class T {
static class C1 extends T { ... }
static class C2 extends T { ... }
}
This would at least eliminate the need to explode each such enumeration into thousand top-level classes in separate files.
For type-aliases, you might consider promoting them to full fledged wrapper classes, but you would have to be very careful whenever instantiating classes like RawData
, using ==
/equals
, hashCode
, or putting them in HashSet
s or HashMap
s. Something like this might work:
class RawData {
private final byte[] value;
public RawData(byte[] v) { ... }
public byte[] getValue() { ... }
public static RawData of(byte[] value) {
return new RawData(value);
}
@Override public int hashCode() {
return value.hashCode();
}
@Override public boolean equals(Object other) {
if (other instanceof RawData) {
return value.equals(((RawData) other).value);
} else {
return false;
}
}
@Override public String toString() {
return String.valueOf(value);
}
}
This would keep the signatures similar, and might even enhance type-safety to some extent. In cases where it is really performance critical, I'd propose to just find/replace all occurrences by byte[]
.
Upvotes: 2