java基础知识复习(反射)

  1. 动态语言:类可以在运行时改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。有:C#,JavaScript,PHP,Python等。
  2. 静态语言:运行时结构不可变的语言。如Java,C++,C。Java不是动态语言,但可以成为“准动态语言”,有一定的动态性:可以利用反射机制、字节码操作获得类似动态语言的特性。
  3. Reflection被视为动态语言的关键,反射机制允许程序在执行期间借助reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
  4. Class是Reflection的根源,需先产生一个Class Object,才能使用reflection相关的API
  5. 加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象,这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构(反射)。
  6. 框架 = 反射+注解+设计模式(待补充
  7. 引入包类名称--通过new实例化--取得实例化对象
    实例化对象--getClass()方法--得到完整的包类名称
  8. 反射提供的功能:
    1)判断任意对象所属的类;构造任意类的对象;判断类所具有的成员变量和方法;处理注解;生成动态代理;
    2)通过反射,可以调用类的私有内部结构,如私有的构造器、私有方法、私有属性。
        public static void main(String[] args) throws Exception {
    
    //      不使用反射创建
            Person person = new Person("Liu",22);
            person.age = 18;
            System.out.println(person.toString());
            person.show();
    //        在Person类的外部,不可以通过Person类的对象调用其内部私有结构
    //        比如name,showNation以及私有的构造器
    
    //      使用反射,创建Person类的对象
    //       通过反射,可以调用Person类的私有内部结构,如私有的构造器、私有方法、私有属性
            Class clazz = Person.class;
            System.out.println(clazz);
            Constructor con = clazz.getConstructor(String.class, int.class);//两个参数的构造器
            Object obj = con.newInstance("Liu",12);
            Person p = (Person)obj;
            System.out.println(p.toString());
            Field age = clazz.getDeclaredField("age");
            age.set(p,18);
            System.out.println(p.toString());
            Method show = clazz.getDeclaredMethod("show");
            show.invoke(p);
    
    //       通过反射,可以调用Person类的私有内部结构,如私有的构造器、私有方法、私有属性
            System.out.println("-----------");
            Constructor con1 = clazz.getDeclaredConstructor(String.class);
            con1.setAccessible(true);
            Person p1 = (Person) con1.newInstance("tom");
            System.out.println(p1);
    
            System.out.println("-----------");
            Field name = clazz.getDeclaredField("name");
    //        保证当前属性是可访问的
            name.setAccessible(true);
    //        参数1:指明设置哪个对象的属性  参数2:将此属性值设置为多少
    //        注:对于静态属性(或方法等)static,参数1可以写为null,一样的效果
            name.set(p1,"Java");
            System.out.println(p1);
    
            System.out.println("-----------");
    //        getDeclaredMethod参数1:指明获取的方法的名称 参数2:指明获取的方法的形参列表
            Method showNation = clazz.getDeclaredMethod("showNation",String.class);
            showNation.setAccessible(true);
    //        showNation.invoke(p1,"中国");
    //        invoke参数1:方法的调用者;参数2:给方法形参赋值的实参;其返回值即为调用方法的返回值
            String nation = (String)showNation.invoke(p1,"中国");
            System.out.println(nation);
        }

    关于java.lang.Class类的理解:

  9. 1)类的加载:将字节码文件(编译生成的.class文件[于硬盘中])加载到内存中。加载到内存中的类,我们就称为运行时类,此运行时类,就作为Class的一个实例。

  10. 2)加载到内存中的运行时类,会缓存一定的时间。在此时间内,我们可以通过不同的方式来获取此运行时类。如下代码,第三种方式使用最多,名称错误在编译时不报错,在运行时报错。

//  获取Class实例的方式(共四种)
    public static void Test1() throws ClassNotFoundException {
//        方式1:调用运行时类的属性.class
        Class clazz1 = Person.class;
        System.out.println(clazz1);
//        方式2:调用运行时类的对象,调用getClass()方法
        Person p1 = new Person();
        Class clazz2 = p1.getClass();
        System.out.println(clazz2);
//        方式3:调用Class的静态方法:forName(String classPath)(使用的最多)
        Class clazz3 = Class.forName("reflection.Base.Person");
        System.out.println(clazz3);
        System.out.println(clazz1 == clazz2);//true
        System.out.println(clazz1 == clazz3);//true
//        方式4:使用类加载器
        ClassLoader classLoader = baseTest.class.getClassLoader();
        Class clazz4 = classLoader.loadClass("reflection.Base.Person");
        System.out.println(clazz1 == clazz4);//true
    }
  1. 创建运行时类的对象:调用newInstance()方法创建对应的运行时类的对象。内部调用了运行时类的空参构造器(此类必须提供了空参构造器且有权限)
  2. 可以有Class对象的类型有:
    1)class : 外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类
    2)  interface接口
    3)[]数组
    4)enum:枚举
    5)annotation:注解@intrerface
    6)permitive type:基本数据类型
    7)void
  3. 复习类的加载过程:
    java基础知识复习(反射)_第1张图片
  4. 通过反射获取运行时类的完整结构:实现的全部接口;所继承的父类;全部的构造器;全部的方法;全部的Field;注解;包;泛型;
  5. public class reflection {
        public static void main(String[] args) {
            String name;
            Date date = new Date();
            if (args.length > 0) {
                name = args[0];
            } else {
                Scanner in = new Scanner(System.in);
                System.out.println("Enter class name (eg. java.util.Date)");
                name = in.next();
            }
            try {
                Class C1 = Class.forName(name);
                Class superC1 = C1.getClass();
                String modifiers = Modifier.toString(C1.getModifiers());
                if (modifiers.length() > 0) System.out.print(modifiers + " ");
                System.out.print("Class " + name);
                if (superC1 != null && superC1 != Object.class) System.out.print("extends " + superC1.getName());
                System.out.print("\n{\n");
                printConstructors(C1);
                printMethods(C1);
                printFileds(C1);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            System.exit(0);
        }
        //打印类中的所有构造函数
        public static void printConstructors(Class c1) {
            Constructor[] constructors = c1.getDeclaredConstructors();
            for (Constructor c : constructors) {
                String name = c.getName();
                System.out.print("  ");
                String modifiers = Modifier.toString(c.getModifiers());
                if (modifiers.length() > 0) System.out.print(modifiers + " ");
                System.out.print(name + "(");
                Class[] paramType = c.getParameterTypes();
                for (int i = 0; i < paramType.length; i++) {
                    if (i > 0) System.out.print(",");
                    System.out.print(paramType[i].getName());
                }
                System.out.println(");");
            }
        }
        //打印类中的所有方法
        public static void printMethods(Class C1) {
            Method[] methods = C1.getDeclaredMethods();
            for (Method m : methods) {
                Class retType = m.getReturnType();
                String name = m.getName();
                System.out.print("  ");
                String modifiers = Modifier.toString(m.getModifiers());
                if (modifiers.length() > 0) System.out.print(modifiers + " ");
                System.out.print(retType.getName() + " " + name + "(");
                Class[] paramType = m.getParameterTypes();
                for (int i = 0; i < paramType.length; i++) {
                    if (i > 0) System.out.print(", ");
                    System.out.print(paramType[i].getName());
                }
                System.out.println(");");
            }
        }
        //    打印类中的所有字段
        public static void printFileds(Class C1) {
            Field[] fields = C1.getDeclaredFields();
            for (Field f : fields) {
                Class type = f.getType();//字段所属类型
                String name = f.getName();//字段名称
                System.out.print(" ");
                String modifiers = Modifier.toString(f.getModifiers());//字段描述符
                if (modifiers.length() > 0) System.out.print(modifiers + " ");
                System.out.println(type.getName() + " " + name + ";");
            }
        }
    }
    
  6. 读取配置文件
    public class ClassLoaderPropre {
        public static void Test1() throws Exception {
            Properties properties = new Properties();
    
    //      方式一:此时配置文件应该放在根目录下(当前module下),而不是src文件下
    //      FileInputStream fis = new FileInputStream("TestMy.properties");//或src//TestMy.properties
    
    //      方式二:此时配置文件应该放在当前module的src文件夹下
            InputStream fis = ClassLoaderPropre.class.getClassLoader().getResourceAsStream("TestMy.properties");
    
            properties.load(fis);
            String user = properties.getProperty("user");
            String password = properties.getProperty("password");
    
            System.out.println("user = " + user + "  password = " + password);
        }
        public static void main(String[] args) throws Exception {
            Test1();
        }
    }

     

  7.  
  8.  
  9.  

 

 

 

你可能感兴趣的:(Java总结)