注解与反射_2 - 小记

1.类加载器的作用?

源文件.java ------ Javac编译器 ------字节码文件.class ------- 类加载器  -------字节码校验器--------解释器 --------OS

作用:将class文件字节码内容,加载到内存中,静态域转化为方法区的运行时刻的数据结构,然后再堆中生成class对象,

作为方法区数据的访问入口。

 

2.类缓存?

查找类,一但加载到类加载器中,将维持/缓存一段时间后,JVM会进行垃圾回收。

 

3.类加载器的分类?

注:util.*   基础类库

1.引导类:复杂核心类库的装载   C++编写
2.扩展类:负责jre/lib/ext 目录下的jar包 或 ext.dirs下的jar包装载入工作库
3.系统类:把properties中的jar包装入工作库。

 4. 双亲委派机制:防止同名包、类与jdk中的相冲突!

加载类时,首先通知appLoader, 是否有缓存 , 能加载即加载;

若无,则通知其父类加载器extLoader , 同上: 是否有缓存 , 能加载即加载;

若无,则通知其父类加载器BootstrapLoader , 同上: 是否有缓存 , 能加载即加载;

若再无?则又一层一层地向子类加载器走,能加载即加载。

若到appLoader,仍然是无缓存,则加载,同时加载到缓存中!

这个过程是不停在找自己的父级,所以叫双亲委派机制。

看下概念!

双亲委派机制描述:
某个特定的类加载器在接到加载类的请求时,
首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;
只有父类加载器无法完成此加载任务时,才自己去加载。
问题:能不能自己写个类叫java.lang.System?

回答:通常情况下不可以,由于类加载采用委托机制。
它会不断查找自己的父类加载器,是否有该同名类,不断递归;

而System类是Bootstrap加载器加载的,就算自己重写,
也总是使用Java系统提供的System,自己写的System类根本没有机会得到加载。


但是!
可以自己定义一个类加载器来达到这个目的,为了避免双亲委托机制,这个类加载器也必须是特殊的。
由于系统自带的三个类加载器都加载特定目录下的类,
如果我们自己的类加载器放在一个特殊的目录,那么系统的加载器就无法加载,
最终由我们自己的加载器加载。

 

5.反射创建类对象?

Class对象调用newInstance()方法;

满足:a.类必须有一个无参构造方法;若无,则必须要传入参数,通过invoke方法;

           b.类的构造方法需要足够。Declared...

 

6.通过构造方法创建对象?

通过Class对象调用getDeclaredConstructer(Class ...parameterTypes)取得构造器方法;

向构造器传入对象数组,包含构造器所需的各个参数;

通过Constructer对象实例化对象。

 

7.调用指定的方法?

getMethod()、invoke()等方法

package com.tencent.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test7 {
    //通过反射创建对象
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {

        Class c1 = Class.forName("com.tencent.reflection.User");

        //1.构造对象 - 调用的无参构造器!
        User user = (User) c1.newInstance();
        System.out.println(user);   //若User未写无参构造,则报错

        //2.通过构造器创建对象
        Constructor constructor = c1.getDeclaredConstructor(String.class , int.class);
        User user1 = (User) constructor.newInstance("jx" , 21);   //如果参数为空,会报错.因为User现没有无参构造方法
        System.out.println(user1);

        //3.利用反射调用普通方法
        User user3 = (User)c1.newInstance();
        //获得一个方法   参数1:方法名  参数2:参数类型
        Method setName = c1.getDeclaredMethod("setName", String.class);
        //invoke激活的意思, (对象 , 方法传参数的值)
        setName.invoke(user3 , "jiaxin");
        Method setAge = c1.getDeclaredMethod("setAge", int.class);
        setAge.invoke(user3 , 21);
        System.out.println("user3 = " + user3);  //User{name='jiaxin', age=21}


        User user4 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        name.setAccessible(true);   //必须加! 开启可访问的权限!  本身不可操作私有属性,所以需要关闭安全检测.
        name.set(user4 , "jx");
        System.out.println(user4);  //User{name='jx', age=0}

    }
}

 8.获得类的属性、方法、构造器?

package com.tencent.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;

public class Test6 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {

        Class c1 =  Class.forName("com.tencent.reflection.User");
        //获得类名字
        System.out.println(c1.getName());       //com.tencent.reflection.User
        System.out.println(c1.getSimpleName()); //User

        //获得类属性
        Field[] fields = c1.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        fields = c1.getDeclaredFields();
        /*
        * private java.lang.String com.tencent.reflection.User.name
        * private int com.tencent.reflection.User.age
        * */
        for (Field field : fields) {
            System.out.println(field);
        }


        //private java.lang.String com.tencent.reflection.User.name
        System.out.println(c1.getDeclaredField("name"));  //私有成员  所以用Declared

        Method[] methods = c1.getDeclaredMethods();
        /*
        public java.lang.String com.tencent.reflection.User.toString()
        public java.lang.String com.tencent.reflection.User.getName()
        public void com.tencent.reflection.User.setName(java.lang.String)
        public int com.tencent.reflection.User.getAge()
        public void com.tencent.reflection.User.setAge(int)
        * */
        for (Method method : methods) {
            System.out.println(method);
        }

        /*
        * 总结:带Declared可以查出私有成员/方法
        * 如果不带,只能查出public的
        * */


        //获得指定构造器 - 根据参数匹配
        Constructor dec = c1.getDeclaredConstructor(String.class , int.class);
        System.out.println(dec);  
    }
}

 

9.获取泛型信息?

public class Test9 {


    public static void t1(Map<String , User> map , List<User> list) {
        System.out.println("t1");
    }

    public static Map<String , User> t2(Map<String , User> map) {
        System.out.println("t2");
        return null;
    }


    public static void test1() throws NoSuchMethodException {
        Method method = Test9.class.getMethod("t1", Map.class, List.class);
        //获取泛型的参数类型
        Type[] types = method.getGenericParameterTypes();
        for (Type type : types) {
            /*
                java.util.Map<java.lang.String, com.tencent.reflection.User>
                java.util.List<com.tencent.reflection.User>
            */
            System.out.println(type);
            //判断type是不是一个结构化参数类型ParameterizedType-类型判断
            if(type instanceof ParameterizedType) {
                Type[] t = ((ParameterizedType) type).getActualTypeArguments();
                for (Type type1 : t) {
                    System.out.println(type1);
                }
            }
            System.out.println("");
        }

        System.out.println("");
    }

    public static void test2() throws NoSuchMethodException {
        Method method = Test9.class.getMethod("t2", Map.class);
        Type typeReturn  = method.getGenericReturnType();
        if(typeReturn instanceof ParameterizedType) {
            Type[] t = ((ParameterizedType) typeReturn).getActualTypeArguments();
            for (Type type : t) {
                System.out.println(type);
            }
            /*
             class java.lang.String
             class com.tencent.reflection.User
            */
        }
    }

    public static void main(String[] args) throws NoSuchMethodException {

    }
}

10.获取注解信息?


//联系反射操作注解
public class Test10 {

    public static void main(String[] args) throws NoSuchFieldException {

        /*
        * ORM: Object relationship Mapping 对象关系映射
        * */

        Class c1 = User.class;

        //通过反射获得类的注解
        Annotation[] annotations =  c1.getDeclaredAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }


        System.out.println("");

        //获得注解的value值
        TableXin table = (TableXin) c1.getAnnotation(TableXin.class);
        String value = table.value();
        System.out.println(value);

        System.out.println("");

        //获得注解的属性
        Field field = c1.getDeclaredField("name");System.out.println(field);
        FieldXin fieldXin = field.getAnnotation(FieldXin.class);
        System.out.println(fieldXin.columnName());
        System.out.println(fieldXin.type());
        System.out.println(fieldXin.length());
        //空指针异常!

    }
}

 

11.注:User类

package com.tencent.reflection;

@TableXin("user")
public class User {

    @FieldXin(columnName = "user_name" , type = "int" , length = 10)
    private String name;

    @FieldXin(columnName = "user_age" , type = "int" , length = 10)
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public User(){}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值