package com.sf.day23;

import org.junit.Test;
import org.omg.IOP.TAG_JAVA_CODEBASE;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.ElementType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Properties;

/**
 * 反射获取class类的四种方法
 */
public class Test01 {
    @Test
    public void t1() throws ClassNotFoundException {
       Class clazz =  String.class;
        /**
         * 获取user类的class类
         * class
         */

        Class<User> userClass = User.class;
        /**
         * 方式二
         * getClass()
         */
        User user = new User();
        Class<? extends User> aClass = user.getClass();

        /**
         * 方式三
         * Class.forName();
         */
        Class<?> aClass1 = Class.forName("com.sf.day23.User");
        Class<?> aClass2 = Class.forName("java.lang.String");


        /**
         * 方式四
         *了解     通过类的加载器进行获取
         */

        ClassLoader classLoader = this.getClass().getClassLoader();
        Class<?> aClass3 = classLoader.loadClass("com.sf.day23.User");

        Class c1 = String.class;
        String obj = new String();
        Class c2 = obj.getClass();
        Class c3 = Class.forName("java.lang.String");
        Class c4 = ClassLoader.getSystemClassLoader().loadClass("java.lang.String");

        System.out.println("c1 = " + c1);
        System.out.println("c2 = " + c2);
        System.out.println("c3 = " + c3);
        System.out.println("c4 = " + c4);

        System.out.println(c1 == c2); //true
        System.out.println(c1 == c3); //true
        System.out.println(c1 == c4);  //true

    }

    @Test
    public void t2(){
     /**
      * 所有的java类型都具有Class类
      */
     Class<Object> objectClass = Object.class;
     Class<Comparable> comparableClass = Comparable.class;
     Class<byte[]> aClass = byte[].class;
     Class<int[]> aClass1 = int[].class;
     Class<ElementType> elementTypeClass = ElementType.class;
     Class<Void> voidClass = void.class;
     Class<Class> classClass = Class.class;
     Class<Test> testClass = Test.class;
     Class<Override> overrideClass = Override.class;
    }

      @Test
      public void t3(){
          int[] a= new int[1];
          int[] b= new int[10];
          int[][]  c = new int[1][2];
       /**
        * 元素类型和维度相同    所对应的class类就相同
        */
     //     System.out.println(a.getClass());
          System.out.println(a.getClass() == b.getClass());
       Class<? extends int[]> aClass = a.getClass();
       Class<? extends int[][]> aClass1 = c.getClass();
     //  System.out.println();
      }

 /**
  * Class类的常用方法
  */

 @Test
 public void t4() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, NoSuchFieldException {
     Class<?> aClass = Class.forName("com.sf.day23.User");
     //  object    --- User    获取当前的id
     Object o = aClass.newInstance();   //创建实例
     if(o instanceof User){
         User user= (User) o;
         Integer id = user.getId();
     }
     System.out.println(aClass);
     System.out.println(o);
     System.out.println(aClass.getName());
     System.out.println(aClass.getSuperclass());
     System.out.println(Arrays.toString(aClass.getInterfaces()));
     System.out.println(aClass.getClassLoader());


     /**
      * Returns:  the array of Constructor objects representing the public constructors of this class
      *
      * Class.getConstructors())   获取当前类的所有 public 构造器
      */
     System.out.println(Arrays.toString(aClass.getConstructors()));

     /**
      * 获取的(public)无参构造器
      */
     System.out.println(aClass.getConstructor());

     /**
      * 获取（public）有参构造器（指定入参的有参构造器）
      */
     System.out.println(aClass.getConstructor(Integer.class));

     /**
      *Returns: the array of Constructor objects representing all the declared constructors of this class
      * 返回所有声明的构造器
      */
     System.out.println(Arrays.toString(aClass.getDeclaredConstructors()));
     System.out.println(aClass.getDeclaredConstructor());
     System.out.println(aClass.getDeclaredConstructor(Integer.class));


     /**
      * 获取所有public修饰的属性
      */
     System.out.println("=================");
     System.out.println(aClass.getField("height"));
     System.out.println(Arrays.toString(aClass.getFields()));
     /**
      * 获取所有声明的属性
      */
     System.out.println(aClass.getDeclaredField("id"));
     //获取属性   进行赋值
     Field field = aClass.getDeclaredField("height");
     /**
      * aClass.newInstance()  当前类的实例
      * 1000      给id这个属性赋的值
      */
     Object o1 = aClass.newInstance();
     field.set(o1,1000.0);
     System.out.println("==========="+o1);
     System.out.println(Arrays.toString(aClass.getDeclaredFields()));

     System.out.println("==============");
     System.out.println(aClass.getMethod("setId",Integer.class));
     System.out.println(Arrays.toString(aClass.getMethods()));
     /**
      * Returns:
      * the array of Method objects representing all the declared methods of this class
      */
     System.out.println(Arrays.toString(aClass.getDeclaredMethods()));
 }



 @Test
 public void t5() throws ClassNotFoundException {
     //获取默认的系统类的加载器
     ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();

     /**
      * 查看某个类是哪个类加载器加载的
      * 是     根加载器加载的    == null
      */
     ClassLoader classLoader = Class.forName("java.lang.String").getClassLoader();
     System.out.println(classLoader);

     /**
      * classLoader   == null
      *
      *                     null.getParent();
      */
     ClassLoader parent = classLoader.getParent();
     System.out.println(parent);
 }

    /**
     * 使用ClassLoader获取流
     */

    @Test
    public void t6() throws IOException {
        Properties properties = new Properties();
        InputStream resourceAsStream = ClassLoader.getSystemClassLoader().getResourceAsStream("db.properties");
        properties.load(resourceAsStream);
        String jdbcusername = properties.getProperty("jdbcusername");
        System.out.println(jdbcusername);
        String jdbcpassword = properties.getProperty("jdbcpassword");
        System.out.println(jdbcpassword);
    }


    @Test
    public void t7() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {

        /**
         * 获取class类的实例
         * 方式一
         * newInstance();
         */
        Class<User> userClass = User.class;
        User user = userClass.newInstance();

        /**
         * 方法二  通过构造器的方式进行获取实例
         */

        Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(Integer.class,String.class);
        User user1 = declaredConstructor.newInstance(1001,"admin");
        System.out.println(user1);

        Constructor<User> declaredConstructor1 = userClass.getDeclaredConstructor(String.class);
        declaredConstructor1.setAccessible(true);   //取消java语言的检查机制   （强行创建）
        User user2 = declaredConstructor1.newInstance("admin");

        System.out.println(user2);

        userClass.getModifiers();


    }
}
