9 Replies Latest reply: Feb 10, 2007 12:00 AM by 807606 RSS

    Need advice on casting...?

    807606
      I have alot of these kinds of methods (see below). They all take ARRAY objects although the object they are cast to (ListElement in the example below) can be different. I am looking to write a generic method to do this. I figured i could use Class.forName() to pass in the class to cast to but i dont know what to put as the method return type (Object?). Any advice appreciated.

      public ListElement toArr(oracle.sql.ARRAY arr) {
      if (arr != null) {
      Object[] o = (Object[])arr.getArray();
      alertTypes = new ListElement[o.length];
      for (int i = 0; i < o.length; i++) {
      alertTypes[i] = (ListElement)o;
      }
      }
      }
        • 1. Re: Need advice on casting...?
          807606
          Hah?
          Try explaining more clearly what u want to do, and post code within "code" tags
          • 2. Re: Need advice on casting...?
            807606
            That method will not compile because there is no return statement in there. What should the method return? A single ListElement or an array of ListElements or something else?

            Please use code tags when you post code.
            • 3. Re: Need advice on casting...?
              807606
              Sorry, i will try again. I have about 5 methods like this (see 2 example methods below). They all return arrays but they are of different types. Apart from that they are identical. I am hoping to merge these methods into 1 generic method that will handle any array type.
              public ListElement[] toArr(oracle.sql.ARRAY arr) {
                 ListElement[] le = null;
                 if (arr != null) { 
                 Object[] o = (Object[])arr.getArray();
                 le = new ListElement[o.length];
                 for (int i = 0; i < o.length; i++) {
                    le = (ListElement)o;
                 }
                 return le;
              }
              
              public AlertType[] toArr(oracle.sql.ARRAY arr) {
                 AlertType[] at = null;
                 if (arr != null) { 
                 Object[] o = (Object[])arr.getArray();
                 at = new AlertType[o.length];
                 for (int i = 0; i < o.length; i++) {
                    at = (AlertType)o;
                 }
                 return at;
              }
              • 4. Re: Need advice on casting...?
                807606
                Generics and arrays don't mix well.

                However a usefull trick is often to pass a Class object. With that you can do a safe cast, and you can also build a correctly typed array.

                Something like:
                public <T> T[]ListElement(oracle.sql.Array arr, Class<T> clazz) {
                ..
                    T[] destArray = (T[])Array.newInstance(clazz, o.length);
                    for(int i = 0; i < o.lenght; o++) 
                         destArray[i] =clazz.cast(o);
                    return destArray;
                  }
                }
                • 5. Re: Need advice on casting...?
                  807606
                  malcolm, I'm not sure he's talking about Generics, just writing a generic method

                  could be wrong, though
                  • 6. Re: Need advice on casting...?
                    807606
                    Hi,

                    Yes, i am looking at writing a generic method rather than using generics. However what you suggested above (passing in the class to cast to) is pretty much what i am looking for.

                    Thanks!
                    • 7. Re: Need advice on casting...?
                      807606
                      Actually one further question! Using the Class object to set it to the object to cast to works fine but what about the method return type? In your answer you are returning ListElement but it could be anything. Would i put Object[] there? Would it still work or would i lose the casting in each slot of the array (i.e. would destArray[0] return Object instead of the actual object type).
                      public <T> T[]ListElement(oracle.sql.Array arr, Class<T> clazz) {
                      ..
                          T[] destArray = (T[])Array.newInstance(clazz, o.length);
                          for(int i = 0; i < o.lenght; o++) 
                               destArray[i] =clazz.cast(o);
                          return destArray;
                        }
                      • 8. Re: Need advice on casting...?
                        807606
                        Sure, but in that case you might as well just return a real Object[] array and not bother with casting inside the method.

                        The elements of an Object[] can be anything, and can be casted to whatever the real object type is.

                        Incidentall it should be (I guess)
                        destArray[i] = clazz.cast(o);
                        • 9. Re: Need advice on casting...?
                          807606
                          Hi There,

                          I am very much confused with the entire casting concept.

                          Below is some codes that I have written and it is very frustrating to see the outcome. I can't seemed to understand the concept.

                          I am sorry, how do you include "code" tag?
                          ..
                          class MySuper{
                               private int superVar;
                               //private int subVar1;

                               public MySuper(){
                                    this.superVar = 100;
                                    //this.subVar1 = 1000;
                               }

                               //public int getSubVar1(){
                               //     return this.subVar1;
                               //}

                               public int getSuperVar(){
                                    return this.superVar;
                               }

                               public void setSuperVar(int superVar){
                                    this.superVar = superVar;
                               }
                          }

                          class MySub extends MySuper{
                               private int subVar1;
                               private int subVar2;

                               public MySub(){
                                    this.subVar1 = 200;
                                    this.subVar2 = 300;
                               }

                               public int getSubVar1(){
                                    return this.subVar1;
                               }

                               public void setSubVar1(int subVar1){
                                    this.subVar1 = subVar1;
                               }

                               public int getSubVar2(){
                                    return this.subVar2;
                               }

                               public void setSubVar2(int subVar2){
                                    this.subVar2 = subVar2;
                               }
                          }

                          public class TestCasting{
                               public static void main(String[] args){

                                    MySuper mySuper = new MySub();
                                    System.out.println("Trying to access MySub behavior as a MySuper object reference");
                                    System.out.println("getSubVar1 ==> " + mySuper.getSubVar1());
                                    //System.out.println("This causes Virtual Method Invocation!!!!\n\n");
                                    System.out.println("Trying to access MySuper behavior as a MySuper object reference");
                                    System.out.println("getSuperVar ==> " + mySuper.getSuperVar() + "\n\n");

                                    System.out.println("Changing reference type from MySuper type back to MySub type");
                                    MySub mySub = (MySub) mySuper;
                                    System.out.println("Trying to access MySub behavior as a MySub object reference");
                                    System.out.println("getSubVar1 ==> " + mySub.getSubVar1() + "\n\n");
                                    System.out.println("Trying to access MySuper behavior as a MySub object reference");
                                    System.out.println("getSuperVar ==> " + mySub.getSuperVar());
                               }
                          }

                          By right, MySub class inherits MySuper and therefore, MySub is a MySuper.

                          When I have a MySuper reference type pointing to MySub object, I should be able to invoke or access the members of MySuper right?

                          MySuper --> MySub(which in this case also inherits MySuper should have the getSuperVar() method)

                          But the above code does not allow me to even compile.

                          Please do explain to me in really simple terms. Thanks.

                          null