1

I have a parent class and a number of child classes (let's call them parent and child1, child2, child3, etc).

I have a function which takes a 2-D array of parents and flattens it to a 1-D array like this:

public parent[] flatten(parent[][] input);

In the calling context, I know that when I pass an array, all of the elements have the same type, and that type is one of the child types (in particular, I know WHICH child type it is). I want to be able to take a particular element of the array, and assign it to a variable of the proper child type like this:

child1 c = flatten(input)[0];

I know about type assertions (relevant SO post: Assert an object is a specific type), but I can't seem to find a way to actually assign to a properly-typed variable if the assertion succeeds. Is such a thing even possible in Java? I know that it's possible in other languages, for example in Go.

Community
  • 1
  • 1
joshlf
  • 21,822
  • 11
  • 69
  • 96

4 Answers4

1

Do you really want to assign it to some Child type. You can work with Parent class reference to access Child class methods, if the method is also defined in Parent class.

Else, you can type cast to appropriate type:

child1 c = (child1)flatten(input)[0];

But, you should be sure that the type is of child1 only. Generally typecasting is not a good idea. It's a sign of bad code (But not always). You should try to avoid it as much as you can.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • Do you know what will happen if I typecast and I'm wrong? It won't happen in this instance; I'm just curious. – joshlf Jun 24 '13 at 19:46
  • It will throw `ClassCastException` at runtime. If you are sure it won't happen here, then it's ok. But it's just a general idea to avoid these kinds of casting. – Rohit Jain Jun 24 '13 at 19:48
  • Hmmm ok cool. My reference is Go, where type casts have to be proven correct at compile time, and type assertions (a separate language construct) are used for casts which cannot be proven until run time. – joshlf Jun 24 '13 at 19:50
1

Try "casting", like this:

Child1 c = (Parent)flatten(input)[0];
morgano
  • 17,210
  • 10
  • 45
  • 56
1

You can't allocate generic arrays, but if you're willing to pass in an out-param you can use generics to take care of the casting for you:

 public <T extends Parent> boolean addAll(T[][] input, 
                                          T[] output) {
   //set up you indices
   output[x] = input[z];
   return true;
}

If you pass in unmatched input/output you'll get a run-time error, otherwise it should just work.

Community
  • 1
  • 1
Paul Rubel
  • 26,632
  • 7
  • 60
  • 80
0

I think it's also worth mentioning that if you don't feel like bothering with the exception handling, you can check the instance of an object.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof

TL;DR: Check the instance of the class you're casting to.

if (flatten(input)[0] instanceof child1)
       Child1 c = (Parent)flatten(input)[0];
Eric
  • 522
  • 5
  • 9