2019-02-22Java中的反射

通过三种方法可以实现反射:
Class clazz=Person.class; //获取反射对象
第二种方法:
Person person=new Person();
person.getClass();
第三种方法:
Class clazz3=Class.forName(“包名+类名”);
下面我们来看一个示例代码(参见Java编程思想317/559):

/**
* 接口1
*/
public interface HasBatteries {

}
public interface Waterproof {
}

public interface Shoots {
}

/**
* 子类
*/
public class FancyToy extends Toy implements HasBatteries,Waterproof,Shoots {
  FancyToy(){
      super(1);
  }
}
下面来看下测试类代码如下:  

public class ToyTest {

  static void printInfo(Class cc){
      //通过输出可以看出 clazz.getName方法获取的是包名+类名

      System.out.println("Class name:"+cc.getName()+" is  interface? [ "+cc.isInterface()+ " ] ");
      System.out.println("Simple name:"+cc.getSimpleName());
      System.out.println("Canonical name :"+cc.getCanonicalName());
  }

  //main函数
  public static void main(String ...args){
       Class c=null ;
       try {
            //第一步通过 class的forName方法通过类包名+类名来获取class对象
            c=Class.forName("practiceDemo14.FancyToy");//注意参数是包名+类名
       }catch (ClassNotFoundException e){
             //如果找不到这个类 就抛出异常
           System.out.println("can not find FancyToy这个类");
       }
       //输出 对象
      printInfo(c);
       System.out.println("======================");
      for(Class face:c.getInterfaces()){
          printInfo(face);
      }
  }
}

执行结果如下:
2019-02-22Java中的反射
Java编程思想上是这么说的:FancyToy这个类继承了Toy并且实现了HasBatteries,Waterproof,和Shoots接口,在main函数中用forName()方法在适当的try语句块中,创建了一个Class引用,并且将其初始化为指向FancyToyClass。注意,在传递给forName的字符串中,你必须使用全限定名(包含包名)
printInfo使用getName方法来产生全限定的类名,并分别使用getSimpleName()和getCanonicalName() 来产生不含包名的类名和全限定的类名。
个人按照输出结果总结:
class.getName() //获取的是传入的包名+类名
class.getSimpleName() //获取的是类名 如果传入的是接口那么获取的就是接口名称
class.getCanonicalName() //获取的也是包名跟类名
class.isInterface() //顾名思义判断的是不是interface接口
class.getInterface() //获取的是数组
class.newInstance() // 该方法是实现 虚拟构造器的一种途径,虚拟构造器允许你声明