class,编程的基础

      我们用了这么久的class,很少有人认真的去看过我们class源码,今天我们来看看Class能带给我们什么?

     一 如何获取class实例:

    方法一:通过类本身获取class实例:

Class clazz1 = Person.class;
System.out.println(clazz1.getName());
   方法二、通过运行时类来获取class实例:

 Person p = new Person();
        Class clazz3=p.getClass();
        System.out.println(clazz3.getName());
   方法三、通过静态方法获取class实例:

 Class clazz4=Class.forName("cn.dandan.test.Person");
 System.out.println(clazz4.getName());
   方法四、通过类加载器获取class实例:

 ClassLoader classLoader=this.getClass().getClassLoader();
Class clazz5= classLoader.loadClass("java.lang.String");
System.out.println(clazz5.getName());  

  二、获取类的完整结构

1.获取类的属性:

@Test
    public void test1(){
    
        Class clazz1= Person.class;
        //只能获得运行类中与父类中生命为public 的属性
        Field[] fields=clazz1.getFields();
        
        for(int i=0;i<fields.length;i++){
            System.out.println(fields[i]);
        }
        
        //可获得本类中所有生命的属性
        Field[] fields1=clazz1.getDeclaredFields();
        
        for(int i=0;i<fields1.length;i++){
            System.out.println(fields1[i]);
        }
    }
  2.获取属性的名称类型及权限

//获取属性中各个部分的内容
    @Test
    public void test2(){
        Class clazz1= Person.class;
        //只能获得运行类中与父类中生命为public 的属性
        Field[] fields=clazz1.getDeclaredFields();
        
        for(Field f : fields){
            //获取每个属性的权限修饰符
            int i = f.getModifiers();
            String str1 = Modifier.toString(i);
            System.out.println(str1+" "+f.getName());
            //获取每个属性的变量类型
            Class type =f.getType();
            System.out.println(type);
            //获取每个属性的名称
            /*System.out.println(f.getName());*/
            System.out.println();
            
        }
    }  
  3.获取注释,修饰符,返回值类型,方法名,形参列表,异常等信息

@Test
    public void test3(){
        
        Class clazz= Person.class;
        Method[] m2= clazz.getDeclaredMethods();
        for(Method m:m2){
            Annotation[] ann= m.getAnnotations();
            for(Annotation a : ann){
                //打印注解的方法
                System.out.println(a);
            }
            //获得返回值的类型
            String str= Modifier.toString(m.getModifiers());
            
            System.out.println(str+" ");
            
            //形参列表
            Class[] type=m.getParameterTypes();
            for(int i=0;i<type.length;i++){
                System.out.println(type[i].getName()+" args-"+i);
            }
            
            Class[] exception= m.getExceptionTypes();
            for(int i=0;i<exception.length;i++){
                System.out.println(exception[i].getName());
            }
            
            /*System.out.println(m);*/
        }
    } 
  4.获取构造器

 @SuppressWarnings("rawtypes")
    @Test
    public void test4() throws ClassNotFoundException{
        String str= "cn.dandan.test.Person";
        Class clazz= Class.forName(str);
        //1.获取构造器
        Constructor[] constructor= clazz.getDeclaredConstructors();
        //
        
        for(int i=0;i<constructor.length;i++){
            System.out.println(constructor[i]);
        }
        //2.获取父类
        Class superClass= clazz.getSuperclass();
        System.out.println(superClass);
        
        //3.获取带泛型的父类
        Type type=clazz.getGenericSuperclass();
        System.out.println(type);
    }
   5.获取带泛型的父类:

 @Test
    public void test5() throws ClassNotFoundException{
        String str= "cn.dandan.test.Person";
        Class clazz= Class.forName(str);
        Class superClass= clazz.getSuperclass();
        Type type=clazz.getGenericSuperclass();
        ParameterizedType paraType=(ParameterizedType)type;
        Type[] ars=paraType.getActualTypeArguments();
        System.out.println(((Class)ars[0]).getName());
    }  
 
  6.获取父类的泛型:

 @Test
    public void test5() throws ClassNotFoundException{
        String str= "cn.dandan.test.Person";
        Class clazz= Class.forName(str);
        Class superClass= clazz.getSuperclass();
        Type type=clazz.getGenericSuperclass();
        ParameterizedType paraType=(ParameterizedType)type;
        Type[] ars=paraType.getActualTypeArguments();
        System.out.println(((Class)ars[0]).getName());
    }
  7.获取实现的接口

   @Test
        public void test6() throws ClassNotFoundException {
            String str= "cn.dandan.test.Person";
            Class clazz= Class.forName(str);
            //获取所在的包
            Package pack = clazz.getPackage();
            System.out.println(pack);
            //获取接口
            Class[] interfaces=clazz.getInterfaces();
            for(int i=0;i<interfaces.length;i++){
                System.out.println(interfaces[i]);
            }
        }  

  三  类加载机制

       我们上面讲了类能给我带来什么,下面我们来说说java的类加载机制。类加载机制就是把类装入内存中。那么,到底是怎么实现的,我们来看下面这张图:

   1.  加载过程:

      java的源程序通过javac编译成.class文件,之后我们使用JVM类加载机制加载.class文件(ps:只有使用的时候才会加载),将此.class文件加载到内存之后就是一个运行时类,并存在缓存区,一个运行时类只加载一次

   2.JVM加载过程中产生三个层次的类加载器,分别为:系统类加载器,扩展类加载器,引导类加载器,具体我们看图



     现在存在这样一种情况,源码中可以获取到系统类加载器,扩展类加载器,但是不能获取到引导类加载器,因为引导类加载器是JVM的核心,所以我们无法获取:

@Test
    public void test5(){
        
        ClassLoader classLoader1=ClassLoader.getSystemClassLoader();
        //获取系统类
        System.out.println(classLoader1);
        //获取扩展类
        System.out.println(classLoader1.getParent());
        //不能获取引导类
        System.out.println(classLoader1.getParent().getParent());
    } 
执行结果:



四 总结:

    有了类,才有了我们面向对象的概念,类给我们提供了很多我们想像不到的东西,好好挖掘吧!


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值