※ 反射:类的镜像

※ 反射

提到反射可能会使我们联想到光学中的反射概念。
在Java中又是另外一个概念:
平时我们照镜子的时候,在镜子后面会有自己的影子,其实java中的反射也是类似的,一个类或者对象通过反射可以获得自身的对象,该对象是一个java.lang.Class 的对象(就像一个镜像文件)。

※ 一个对象或者类获得自身的Class对象的过程称为反射。
※ 反射一般用于,当只有一个类对象没有源代码的时候,为了获取类中方法和属性,构造器等。

※ Class类型 java.lang.Class类

1)Class是对java中所有类型的抽象。即一个Class类型对象可以表示出java中任意一种类型。
2)每种类型在加载到内存后,内存中都会生产一个与之对应的Class类型对象(有且只有一个),用来表示该类型。
3)每个类型都有且只有一个Class类型对象与之对应,通过这个Class类型对象就可以获得到该类型中的各种信息。

※ Class类是Java反射的入口.
反射机制通过在运行时探查字段和方法,从而可以帮助写出通用性很好的程序,这项能力对系统编程来说特别有用,但它并不适合于应用编程。而且,反射是脆弱的——编译不能帮助你发现编译错误,任何错误在运行时被发现并且都会导致异常。

1.表示基本类型

                Class c = int.class;
                System.out.println(c.isPrimitive());//true
                System.out.println(c.getName());//int

            注:其他基本类型的情况类似

2.表示类类型

注:s.getClass()方法返回的是变量s所指向对象的实现类型的Class对象。
            Student s = new Student();
            Class c1 = s.getClass();
            Class c2 = Student.class;
            System.out.println(c1 == c2);//true

            //p指向的对象实际类型是Student
            Person p = new Student();
            Class c1 = p.getClass();//c1表示Student类型
            Class c2 = Person.class;//c2表示Person类型
            System.out.println(c1 == c2);//false

3.表示接口类型

            Action a = new Student();
            Class c1 = a.getClass();//c1表示Student类型
            Class c2 = Action.class;//c2表示Action类型
            System.out.println(c1 == c2);//false

            System.out.println(c2.isInterface());//true

4.表示数组类型

        int[] a = new int[4];
            Class c1 = a.getClass();
            Class c2 = int[].class;
            System.out.println(c1 == c2);//true
            System.out.println(c1.isArray());//true

            Class c3 = c1.getComponentType();//c3表示该数组是使用什么类型声明出来的
            System.out.println(c3.getName());//int



            Student[] a = new Student[4];
            Class c1 = a.getClass();
            Class c2 = Student[].class;
            System.out.println(c1 == c2);//true
            System.out.println(c1.isArray());//true

            Class c3 = c1.getComponentType();//c3表示该数组是使用什么类型声明出来的
            System.out.println(c3.getName());//com.briup.test.Student

※ 获取镜像的方法

※ 获取基本数据类型的镜像

Class c=int.class
//false,Integer是包装类,不是基本数据类型
//Class c=Integer.class;
System.out.println(c);

※ 获取类(引用类型)的镜像
有三种方法可以获得自身的Class对象引用(对每一个被装载的类型(类或接口),虚拟机都会为它创建一个
java.lang.Class的实例);
1)虚拟机中没有该类的Class的实例对象,借助全包名.类名(全包名.接口名)。

try {
            Class c2=Class.forName("com.briup.collection.map.ShopCart");
            System.out.println(c2);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }  

2)知道类名时,直接类名.class获取镜像;

    Class c1=ShopCart.class;
    System.out.println(c1); 

3)有类的实例时,基于对象获取镜像。

ShopCart cart=new ShopCart();
Class c=cart.getClass();
System.out.println(c);

注意:类和它所创建的所有对象通过反射获得的Class对象都是同一个。

※ 反射机制中的常见类的含义

    java.lang包下:
    Class  类    对java中所有类型抽象而得来的
    package类    对java中所有包抽象而得来的

    java.lang.reflect包下:
    Modifier    类   对java中所有修饰符抽象而得来的
    Field       类   对java中所有属性抽象而得来的
    Method      类   对java中所有方法抽象而得来的
    Constructor 类   对java中所有构造器抽象而得来的
    Array       类   提供了对数组对象的动态访问

※ 反射的作用

反射可以让我们利用这个Class对象来获取和修改私有的变量和方法,不通过共有的方法去获得(原来我们例子都是通过一个public的方法来设置和获取私有的变量),可以破坏数据的封装性。

常用到反射方式:
1) 可以创建对象
2) 可以访问对象中的属性
3) 可以访问对象中的方法。
4) 可以访问对象中的构造器。

反射机制通过在运行时探查字段和方法,从而可以帮助写出通用性很好的程序,这项能力对系统编程来说特别有用,但它并不适合于应用编程。而且,反射是脆弱的——编译不能帮助你发现编译错误,任何错误在运行时被发现并且都会导致异常。

※ java.lang.Class类(API)

我们通过Class类,实现了反射的作用:例如:得到类的镜像名字,调用镜像类中属性,方法,构造器德等。
※ Class类中方法:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
※ 关于类镜像的一些方法的验证:

package com.briup.reflect;

import com.briup.collection.map.Cart;

public class FirstReflect {
    public void test(){
        //获取基本数据类型的镜像
        Class c=int.class;
        System.out.println(c);
        //获取镜像的名字
        System.out.println(c.getName());
        //判断某个镜像是不是基本数据类型
        System.out.println(c.isPrimitive());
    }
    public void test1(){
        //同一类型不管构建多少对象,模版都是一个
        int [] n=new int[10];
        int [] n1=new int[30];
       boolean[] b=new boolean[10];
        Class bc=b.getClass();
        Class c=n.getClass();
        Class c1=int[].class;
        Class c2=n1.getClass();
//      System.out.println(c1.getName());
//      System.out.println(c2.getName());
//      System.out.println(bc.getName());
        //判断某一个镜像是不是一个数组的镜像
        System.out.println(c1.isArray());
    }
    public void test2(){
        //父类指向子类,获取的镜像是子类的,
        Parent p=new Children();
        Class c=Parent.class;
        Class c1=p.getClass();
        System.out.println(c);
        //判断c1是不是c镜像的子类(子实现)
        System.out.println(c.isAssignableFrom(c1));
    }
    public void test3(){
        A ch=new Children();
        Class c=ch.getClass();
        Class c1=A.class;
//      A b=new A(){};
//      System.out.println(c1==b.getClass());
//      System.out.println(c1);
        //判断镜像是不是接口类型
        System.out.println(c1.isInterface());
        //判断c是不是c1的子实现
        System.out.println(c1.isAssignableFrom(c));
        Cart[] n=new Cart[10];
        Class c2=n.getClass();
        //获取数组镜像的类型
        System.out.println(c2.getComponentType());
    }
    public void test4(){
        //如果是基本数据类型,镜像的获取
        Class c=int.class;
        //如果是引用类型 镜像的获取3种
        //构建对象的方法获取 getClass()
        Cart cart=new Cart();
        Class c1=cart.getClass();
        //通过类名.class        接口.class  数组类型[].class
        Class c2=Cart.class;
        Class c3=A.class;
        Class c4=Cart[].class;
        //通过包名+类名(接口的名字获取镜像)
        try {
            Class c5=Class.forName("com.briup.collection.map.Cart");
            System.out.println(c5);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        FirstReflect f=new FirstReflect();
        f.test4();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值