zoukankan      html  css  js  c++  java
  • 黑马程序员——反射总结

    ---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------


    Class类:(再讲反射之前必须得先知道Class类)

    Class:代表一类事物是一个类,用于描述众java类的一个类

    Class类特点:没有构造方法,它的实例对象是各个类在内存中的字节码

    如何得到各个类对应的字节码:1、类名.class 2、对象.getClass() 3、Class.forName("类名")-->静态方法


    得到字节码的三种方式的验证代码片段:

    String str = ""abc";

    使用各种方法得到str对象的字节码文件

    Class cl1 = String.class;

    Class cl2 = str.getClass();

    Class cl3 = Class.forName("java.lang.String");//此处类名是类全名

    进行判断

    sop(cl1 == cl2);  //true

    sop(cl1 == cl3); //true

    打印结果为两个true,证明三种方式得到的字节码都是同一字节码


    Class类的几个方法:

    Class.isPrinitive();判断一个类是不是基类int.class == Integer.TYPE;

    Class.isArray();判断class的类型

    只要在源程序中出现的类型,都有各自的class实例对象例如:int[] 、void

    java中有九个预定义Class实例对象:八个基本数据类型,一个void.class();


    *-*_______________________________________________________________*-*


    反射:(JDK1.2)

    何为反射:反射就是通过Java类中的各种成分映射成相应的Java类

    反射的使用:1、首先得到要调用类的字节码class 2、然后得到要调用类中的方法Method 3、在进行方法的调用(invoke)

    Constructor类获取class类的构造方法,使用相应的构造方法创建相应的对象,所得对象就可以使用相应的类的方法

    代码实例片段:

    Constructor constructor1 = String.class.getConstructor(StringBuffer.class);

    String str = constructor1.newInstance(new StringBuffer("abc"));//传入与constructor1同类型的参数

    sop(str.charAt(2)); //c

    Field类:获得字节码里某一变量的字段,然后通过对象得到相应的值

    代码实例片段:(先定义一个类,然后通过反射得到类实例对象的各项值)

    public class ReflectPoint

    {

    private int x;

    public int y;

    public ReflectPoint(int x, int y)

    {

    this.x = x;

    this.y = y;

    }

    }

    · 应用↓

    ReflectPoint pt1 = new ReflectPoint(3, 5);

    Field fieldY = pt1.getClass().getField("y");

    sop(fieldY.get(pt1));//5

    想要得到私有变量需要使用暴力反射,将其变量设为可见

    Field fieldX = pt1.getClass().getDeclaredField("x");

    fieldX.setAccessible(true);

    sop(fieldX.get(pt1));//3

    代码实例获取字段并修改:

    //首先创建一个类

    public class ReflectPoint

    {

    public String str1 = "ball";

    public String str2 = "basketball";

    public String str3 = " itcast";

    }

    //然后对类中的成员获取字段并作替换,具体实现步骤:1、先获得相应对象所有字段 2、遍历得到目标类型变量字段 3、获得字段值,修改后设置对象值

    Field[] fields = pt2.getClass().getFields();

    for(Field field : fields)

    {

    if(field.getTYPE == String.class)//字节码对应同一字节码故用 ==

    {

    String value = (String)field.get(pt2);

    value = value.replaace('b', 'a');

    field.set(pt2, value);

    }

    }

    Method类:获得类中的方法,再通过方法调用类中对象

    代码片段:

    Method methodCharAt = String.class.getMethod("charAt", int.class);

    sop(methodCharAt.invoke(str, 1));//获取str中的第二个元素,调用静态方法时第一个参数为null,方法返回值由方法本身决定

    //

    ①②③④⑤⑥⑦⑧⑨⑩

    用反射的方式执行某个类的main方法:

    1、获取需要执行的main方法 2、传入参数调用main方法启动

    代码片段:

    ①String startingClassName = args[0];	//在不明确具体调用的类的时候
    Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
    mainMethod.invoke(null, (object)new String[]{ });
    ②Method mainMethod = 类名.class.getMethod("main", String[].class);	//明确调用类的类名的时候也可以直接获取其main方法
    mainMethod.invoke(null, (object)new String[]{ });	//加Object将数组强转为了能满足JDK1.4的语法,当传入参数只有一个的时候可以省略
    	数组的反射:
    	1、具有相同数据类型和相同维度的数组对应相同的字节码文件
    	2、数组class实例对象.getSuperClass();返回Object对应的class文件即:Object.class
    	3、基本类型的一维数组可以当做Object类型使用,非基本类型即可当Object也可当Object[]
    	4、Arrays.asList();处理int[]和String[]差异:基本数据把整个数组当做一个元素
    	5、怎样得到数组中的元素类型:先取出一个元素,再得到字节码,最后获得类型		a[0].getClass().getName();
    	数组反射的应用:判断一个数组是否为基本型,如果是对其中的元素进行操作
    	代码片段:
    printObject(a);
    private static void printObject(Object obj){
    	Class cl = obj.class();
    	if(cl.isArrar()){
    		int len = Array.getLength(obj);
    		for(int i=0; i<len; i++){
    			sop(Array.get(obj, i));
    		}
    	}else{
    		sop(obj);
    	}
    }
    
    

    反射实现框架功能:

    框架与框架要解决的核心问题:框架与工具之间的相互调用
    框架要解决的核心问题:在不明确调用框架的具体类时,利用反射方式实现运行程序的提前安排
    实例代码片段:
    InputStream ips = new FileInputStream("config.properties");//当要使用时对配置文件具体配置
    Properties props = new properties();
    props.load(ips);
    ips.close();
    String className = props.getProperty("className");
    Collection collections = (Collection)class.forName(className).newInstance();
    ...
    collections.add(...);
    配置文件的加载:
    1、getRealPath(); 查找根目录
    2、InputStream ips = 类名.class.getClassLoader().getResourceAsstream("文件名");




    ---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

    用心-细心-专心-决心 学习就像爬大山,一步一步向前走 -态度决定高度-
  • 相关阅读:
    css实现左栏固定右栏自适应,高度自适应的布局
    使用canvas检测HTML5视频解码错误
    与webview打交道中踩过的那些坑
    走进AngularJs(五)自定义指令----(下)
    走进AngularJs(四)自定义指令----(中)
    走进AngularJs(三)自定义指令-----(上)
    为jQuery的$.ajax设置超时时间
    走进AngularJs(二) ng模板中常用指令的使用方式
    走进AngularJs(一)angular基本概念的认识与实战
    Javascript事件模型系列(四)我所理解的javascript自定义事件
  • 原文地址:https://www.cnblogs.com/xianyou-liang/p/8503357.html
Copyright © 2011-2022 走看看