java反射

一、什么是反射:

Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。)语言的一个关键性质。


二、反射机制主要提供以下功能:

①在运行时判断任意一个对象所属的类;

②在运行时构造任意一个类的对象;

③在运行时判断任意一个类所具有的成员变量和方法;

④在运行时调用任意一个对象的方法;

⑤生成动态代理。


三、反射机制的优缺点

1、优点:

在运行时获得类的各种内容,进行反编译,对于Java这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。

2、缺点:

(1)反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;

(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。


四、反射的作用

    • 动态创建对象
    • 动态操作属性
    • 动态调用方法

在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中


  • 六、Class类的常用方法:

    getFields()—— 获得类的public类型的属性。

    getDeclaredFields()—— 获得类的所有属性

    getField(String name)—— 获得类的指定属性

    getMethods()—— 获得类的public类型的方法

    getMethod (String name,Class [] args)—— 获得类的指定方法

    getConstrutors()—— 获得类的public类型的构造方法

    getConstrutor(Class[] args)—— 获得类的特定构造方法

    newInstance()—— 通过类的无参构造方法创建对象

    getName()—— 获得类的完整名字

    getPackage()—— 获取此类所属的包

    getSuperclass()—— 获得此类的父类对应的Class对象


    七、代码演示:认知Class类

    • Class类:代表一个类
    • Constructor 类:代表类的构造方法
    • Field 类:代表类的成员变量(属性)
    • Method类:代表类的成员方法

      五、反射的入口—Class类

      -Class类是Java 反射机制的起源和入口

    • 用于获取与类相关的各种信息
    • 提供了获取类信息的相关方法
    • Class类继承自Object类
    • -Class类是所有类的共同的图纸

    • 每个类有自己的对象,好比图纸和实物的关系
    • 每个类也可看做是一个对象,有共同的图纸Class,存放类的结构信息,比如类的名字、属性、方法、构造方法、父类和接口,能够通过相应方法取出相应信息
    • -Class类的对象称为类对象

  • public class TestClass1 {
        public static void main(String[] args) throws Exception {
            //1.获取一个类的结构信息(类对象 Class对象)
            Class clazz = Class.forName("com.bjsxt.why.Dog");
            //2.从类对象中获取类的各种结构信息
            //2.1 获取基本结构信息
            System.out.println(clazz.getName());
            System.out.println(clazz.getSimpleName());
            System.out.println(clazz.getSuperclass());
            System.out.println(Arrays.toString(clazz.getInterfaces()));
            //2.2 获取构造方法
            //只能得到public修饰的构造方法
            //Constructor[] constructors = clazz.getConstructors();
            //可以得到所有的构造方法
            Constructor[] constructors = clazz.getDeclaredConstructors(); 
            System.out.println(constructors.length);
            for(Constructor con :constructors){
                //System.out.println(con.toString());
                System.out.println(con.getName() + "||" + 
                        Modifier.toString(con.getModifiers())+"  ||"
                        + Arrays.toString(con.getParameterTypes()));
            }
            //Constructor con = clazz.getConstructor();//获取无参数构造方法
          //Constructor con = clazz.getConstructor(String.class,String.class);
            Constructor con = 
    clazz.getDeclaredConstructor(String.class,String.class);
            System.out.println(con);
            //2.3 获取属性
           //Field[] fields = clazz.getFields();
            Field [] fields = clazz.getDeclaredFields();
            System.out.println(fields.length);
            for(Field f :fields){
                System.out.println(f);
            }
            //Field f = clazz.getField("color");
            //private 默认 protecte public都可以获取,但不包括父类的
            Field f = clazz.getDeclaredField("age");
            System.out.println(f);
            //2.3 获取方法
           //Method[] methods = clazz.getMethods();
            Method [] methods = clazz.getDeclaredMethods();
            for(Method m : methods){
                System.out.println(m);
            }
            //Method m = clazz.getMethod("shout",String.class);
            //Method m = clazz.getMethod("run");//public
            Method m = clazz.getDeclaredMethod("run");
            System.out.println(m);
        }
    }

    八、获取一个类的类对象的三种方式:

    public class TestClass2 {
        public static void main(String[] args) throws  Exception {
            //1.获取一个类的结构信息(类对象 Class对象)
            // 1.1Class.forName(类的完整路径字符串);
            //Class clazz = Class.forName("java.lang.String");
            //1.2 类名.class
           // Class clazz = String.class;
            //1.3 对象名.getClass()
            String str = "bjsxt";
            Class clazz = str.getClass();
            //Integer in = new Integer(20);
            //2.从类对象中获取类的各种结构信息
            System.out.println(clazz.getName());
            System.out.println(clazz.getSimpleName());
            System.out.println(clazz.getSuperclass());
            System.out.println(Arrays.toString(clazz.getInterfaces()));
        }
    }

    其中类名.class、对象名.getClass()方式在编码时已经知道了要操作的类,而Class.forName()方式在操作的时候,可以知道,也可以不知道要操作的类。所以当编码时还不知道要操作的具体类,就只能使用Class.forName()方式了。

 九、实操:

     1.创建项目,导入jar

2.按照如下目录结构创建接口及其实现类,

 

 service

 servlet

 

 

 外部文件

 testservlet实现效果

 test01实现效果

  test02实现效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值