Class里的方法

1. getClasses 和 getDeclaredClasses

  • getDeclaredClasses 获取到类里所有的的class ,interface 包括了private ,protected,default,public

例子:
定义一个Payment的基本类如下

public class Payment {
    protected class InnerPayment{
    }
    String name;
    interface Account{}
    public class InnerAccount implements Payment.Account{
    }
    private class InnerAccount2 implements Payment.Account{
    }
}

测试

public class PaymentReflectTest {
    public static void main(String[] args) {
      Class[] cls=Payment.class.getDeclaredClasses();//获取到所有的定义的class
        for (int i = 0; i <cls.length ; i++) {
            System.out.println(cls[i]);
        }
    }
}

打印出来的结果如下

class rechard.learn.reflect.Payment$InnerAccount2
class rechard.learn.reflect.Payment$InnerAccount
interface rechard.learn.reflect.Payment$Account
class rechard.learn.reflect.Payment$InnerPayment
  • getClasses 只获取到public
    上面的测试代码改成
   Class[] cls=Payment.class.getClasses();
        for (int i = 0; i <cls.length ; i++) {
            System.out.println(cls[i]);
        }

只获取到

class rechard.learn.reflect.Payment$InnerAccount

2. getConstructors 和 getDeclaredConstructors

  • getDeclaredConstructors 打印出类的所有的构造函数
   Class[] cls=Payment.class.getDeclaredClasses();
        for (int i = 0; i <cls.length ; i++) {
            Constructor[] cs= cls[i].getDeclaredConstructors();
            for (int j = 0; j <cs.length; j++) {
                System.out.println(cs[j]);
            }
        }

打印的结果如下

private rechard.learn.reflect.Payment$InnerAccount2(rechard.learn.reflect.Payment)
public rechard.learn.reflect.Payment$InnerAccount(rechard.learn.reflect.Payment)
protected rechard.learn.reflect.Payment$InnerPayment(rechard.learn.reflect.Payment)
public class Payment {
 public static class InnerStaticAccount implements Payment.Account{
 }
 }
  • getConstructors 打印出类的public构造函数

3. new instance

如何new Payment里的InnerAccount

public class Payment {
      protected class InnerAccount implements Payment.Account{
        private String acctNumber;
        public InnerAccount(String acctNumber){
            this.acctNumber=acctNumber;
        }

        public String getAcctNumber() {
            return acctNumber;
        }

        @Override
        public String toString() {
            return "InnerAccount{" +
                    "acctNumber='" + acctNumber + '\'' +
                    '}';
        }
    }
}

如果 new InnerAccount 的类不和Payment 在同一个package下,写成如下,会报错,InnerAccount为proctected 不可见:

new Payment().new InnerAccount("111111");

改成以下代码调用

        Class[] cls = Payment.class.getDeclaredClasses();
        for (int i = 0; i < cls.length; i++) {
           if(cls[i].getSimpleName().equals("InnerAccount")){
               try {
                   Constructor c=(Constructor)cls[i].getDeclaredConstructor(Payment.class,String.class);
                   c.setAccessible(true);
                   System.out.println(c.newInstance(new Payment(),"123"));
               } catch (Exception e) {
                   e.printStackTrace();
               }
           }
        }

其实这样构造出来的有诸多不变,上面的c.newInstance(new Payment(),"123"),没法用一个实际的引用的引用,只能用Object o 来引用,如果如果要调用getAcctNumber(),只能通过反射来调用,如下:

 Class[] cls = Payment.class.getDeclaredClasses();
        for (int i = 0; i < cls.length; i++) {
           if(cls[i].getSimpleName().equals("InnerAccount")){
               try {
 Constructor c=(Constructor)cls[i].getDeclaredConstructor(Payment.class,String.class);
                   c.setAccessible(true);
                   Object o=c.newInstance(new Payment(),"123");
                   Method m=o.getClass().getMethod("getAcctNumber",null);
                   System.out.println(m.invoke(o,null));
                   }catch (Exception e) {
                   e.printStackTrace();
               }
           }
 }
06-07 01:15