//reflect.java  --- @CopyLeft by tsaiwn@csie.nctu.edu.tw
//Demo Java Reflection --- Dynamic type checking  (java.lang.reflect.*)
import java.util.*;    // import java.lang.reflect.*
class reflect{
   static java.io.PrintStream cout = System.out;
   public static void main(String xxx[ ]) {
       int a = 38;  int x[ ] = { 33, 88, 58};
       Integer y[ ] = { 33, 88, 58, 888, 567, 666, 555, 258};
 String s = "abced"; String sa[ ] = { "abc", "33", "888", "ggg", "58"};
       Class ic = int.class;  print("ic: "); test(ic);
       print("x: "); test(x); print("y: "); test(y);
       print("s: "); test(s);  print("sa: "); test(sa);
       Student stu = new Student( ); print("stu: "); test(stu);
       Student[ ]stuary = new Student[6]; print("stuary: "); test(stuary);
       try{
          Class tt = Class.forName("Student"); 
          Object gg= tt.newInstance( );   // ¥Í¥X¤@­Ó Student
          print("gg: "); test(gg);   // gg is a Student
          Class ggType = gg.getClass( );
          print(" is gg an instance of Student? ");
          println( "" + ggType.isInstance(new Student( ) ) );
          cout.print(" Fields name of gg: "); pfd(gg);
       }catch(Exception e){;}
   } //main(
   static void print(String s) { cout.print(s); }
   static void println(String s) { cout.println(s); }
   static void printf(String s, Object... y) { cout.printf(s, y); }
   static void test(Object x) {
      Class whatWG = x.getClass( );   // ½¼±K¸J¿|  
      print( "type name=" +whatWG.getName( ) + " ; ");
      if(whatWG.isArray( ) ) {
         Class elementType = whatWG.getComponentType();
         print("\n    is Array of " + elementType);
         print(" ; Array size: " + java.lang.reflect.Array.getLength(x));
         if(elementType.isPrimitive( ) ) println(", element is Primitive");
         else {  // is Object
            print(", element NOT Primitive\n  --> its element: ");
            try{
               Object y = java.lang.reflect.Array.get(x, 0); //x[0]
               test(y);  // recursice call my self
            }catch(Exception e){ println(" x[0] NOT exist!  null ?");}
         }//if..else
      } else println(" NOT an Array");   // if .. isArray(
   }//test(
   static void pfd(Object x){
      Class whatWG = x.getClass( );   // ½¼±K¸J¿|  
      java.lang.reflect.Field fd[ ]= whatWG.getDeclaredFields( );
      for(int i=0; i< fd.length; ++i) cout.print(" "+fd[i].getName( ));
      cout.println( );
   }//pfd(           // also try  getDeclaredMethods( ),  getMethods( )
}//class 
class Student implements Comparable<Student>{
    String id, name;
    int height=0; float wet=0;
    public int compareTo(Student b){return height - b.height;}
};
/***********
D:\COURSE\OOP\ppnt>javac reflect.java

D:\COURSE\OOP\ppnt>java reflect
ic: type name=java.lang.Class ;  NOT an Array
x: type name=[I ;
    is Array of int ; Array size: 3, element is Primitive
y: type name=[Ljava.lang.Integer; ;
    is Array of class java.lang.Integer ; Array size: 8, element NOT Primitive
  --> its element: type name=java.lang.Integer ;  NOT an Array
s: type name=java.lang.String ;  NOT an Array
sa: type name=[Ljava.lang.String; ;
    is Array of class java.lang.String ; Array size: 5, element NOT Primitive
  --> its element: type name=java.lang.String ;  NOT an Array
stu: type name=Student ;  NOT an Array
stuary: type name=[LStudent; ;
    is Array of class Student ; Array size: 6, element NOT Primitive
  --> its element:  x[0] NOT exist!  null ?
gg: type name=Student ;  NOT an Array
 is gg an instance of Student? true
 Fields name of gg:  id name height wet
*********************************/
