5 Replies Latest reply on Mar 30, 2005 5:52 PM by hlovatt

    Array Class Literals

    hlovatt

      Hi,

      The following code fails in the Javassist compiler:

      if ( $3 instanceof Object[].class )
       return $3.length;


      Instead I have to use:

      Class array = java.lang.reflect.Array.newInstance( Object.class, 0 ).getClass();
      if ( array.isInstance( $3 ) )
       return $3.length;


      Are there plans to add array class literals?

      Is there a better work around?

      Keep up the good work - Howard.

        • 1. Re: Array Class Literals
          hlovatt

          Ignore - I forgot to watch the topic :)

          • 2. Re: Array Class Literals
            chiba

            Let me make sure.
            Javassist 3 can compile Object[].class.

            Chiba

            • 3. Re: Array Class Literals
              hlovatt

              3 couldn't when I tried the above example.

              Howard.

              • 4. Re: Array Class Literals
                chiba

                Really?
                Can you post a complete test case?
                Thanks!

                • 5. Re: Array Class Literals
                  hlovatt

                  First two appologies: I don't seem to be able to watch this thread so I missed your post and secondly my test class is a little long :( . Take a look at lines 75 to 90 which demonstrate the problem I am having with array class literals and also with testing for null on primitive arrays (see seperate post to this forum for null problems).

                  package examples.javassisttests.poolget;
                  
                  import javassist.*;
                  import pec.compile.*;
                  import java.io.*;
                  import java.lang.reflect.*;
                  
                  public class Test {
                   static class Y {}
                   static class X extends Y {}
                   public static void main( final String[] notUsed ) throws Exception {
                   // Test of assignment compatability
                   final X[] xs = new X[ 1 ];
                   final Y[] ys = xs;
                   ys[ 0 ] = new X(); // OK
                   // ys[ 0 ] = new Y(); // ArrayStoreException
                   final ClassPool pool = ClassPool.getDefault();
                   final CtClass intClass = pool.get( "int" );
                   final CtClass longClass = pool.get( "long" );
                   System.out.println( "Class: " + long.class.isAssignableFrom( int.class ) );
                   System.out.println( "CtClass: " + longClass.subtypeOf( intClass ) );
                  
                   // get classes
                   System.out.println( "int = " + intClass );
                   final CtClass intArrayClass = pool.get( "int[]" );
                   System.out.println( "int[] = " + intArrayClass );
                   final CtClass objectArrayClass = pool.get( "java.lang.Object[]" );
                   System.out.println( "Object[] = " + objectArrayClass );
                  
                   // class definition (AbstractTest)
                   final CtClass clazz = pool.makeClass( "examples.javassisttests.poolget.AbstractTest" );
                   clazz.setModifiers( javassist.Modifier.ABSTRACT );
                   clazz.setModifiers( javassist.Modifier.PUBLIC );
                  
                   // protected constructor definition
                   final CtConstructor constructor = CtNewConstructor.defaultConstructor(
                   clazz );
                   constructor.setModifiers( javassist.Modifier.PROTECTED );
                   clazz.addConstructor( constructor );
                  
                   // abstract method definition
                   final CtClass[] arguments = new CtClass[] { intClass, intArrayClass, objectArrayClass };
                   final CtMethod method = CtNewMethod.abstractMethod(
                   intClass,
                   "f",
                   arguments,
                   null,
                   clazz );
                   clazz.addMethod( method );
                  
                   // write the abstract class
                   clazz.writeFile( "C:\\Personal\\Java" );
                  
                   // print the abstract class
                   final Class classOfClazz = Class.forName( "examples.javassisttests.poolget.AbstractTest" );
                   System.out.println();
                   Utilities.printSignature( classOfClazz, null );
                  
                   // class definition (DerivedTest)
                   final CtClass derivedClass = pool.makeClass(
                   "examples.javassisttests.poolget.DerivedTest", clazz );
                   derivedClass.setModifiers( javassist.Modifier.PUBLIC );
                  
                   // public constructor definition
                   final CtConstructor derivedConstructor = CtNewConstructor.defaultConstructor(
                   derivedClass );
                   derivedClass.addConstructor( derivedConstructor );
                  
                   // method definition
                   final CtMethod derivedMethod = CtNewMethod.make(
                   intClass,
                   "f",
                   arguments,
                   null,
                   /*"{\n" +
                   " if ( $2 != null )\n" +
                   " return $2.length;\n" +
                   " if ( $3 instanceof Object[].class )\n" +
                   " return $3.length;\n" +
                   " return $1;\n" +
                   "}",*/
                   "{\n" +
                   " if ( System.identityHashCode( $2 ) != 0 )\n" +
                   " return $2.length;\n" +
                   " Class array = java.lang.reflect.Array.newInstance( Object.class, 0 ).getClass();\n" +
                   " if ( array.isInstance( $3 ) )\n" +
                   " return $3.length;\n" +
                   " return $1;\n" +
                   "}",
                   derivedClass );
                   derivedClass.addMethod( derivedMethod );
                  
                   // write the derived class
                   derivedClass.writeFile( "C:\\Personal\\Java" );
                  
                   // print derived class
                   final Class classOfDerivedClazz = Class.forName( "examples.javassisttests.poolget.DerivedTest" );
                   System.out.println();
                   Utilities.printSignature( classOfDerivedClazz, null );
                  
                   // Test DerivedTest
                   System.out.println();
                   final Method methodF = classOfDerivedClazz.getMethod( "f", new Class[] { int.class, int[].class, Object[].class } );
                   final Object dt = classOfDerivedClazz.newInstance();
                   int value;
                   value = ((Integer) methodF.invoke( dt, new Object[] { new Integer( 1 ), null, null } )).intValue();
                   System.out.println( "f() = " + value );
                   value = ((Integer) methodF.invoke( dt, new Object[] { new Integer( 1 ), new int[ 2 ], null } )).intValue();
                   System.out.println( "f() = " + value );
                   value = ((Integer) methodF.invoke( dt, new Object[] { new Integer( 1 ), null, new Object[ 3 ] } )).intValue();
                   System.out.println( "f() = " + value );
                   }
                  }