Java基础之—反射(高级用法)

一、项目中最常见用法 (读取配置文件)

package com.todoming.reflect;
import java.io.FileReader;
import java.lang.reflect.Method;
import java.util.Properties;
public class ReadProperties {
    //获取配置文件属性
    public static String getValue() throws Exception{
        //获取配置文件的对象
        Properties properties=new Properties();
        //获取输入流
        FileReader reader=new FileReader("app.properties");
        //将流加载到配置文件对象中 
        properties.load(reader);
        reader.close();
        return properties.getProperty("message");
    }
    public static void main(String[] args) throws Exception{
        Class cla = Class.forName(getValue());
        Method method = cla.getDeclaredMethod("showMessage",String.class);
        Object object = cla.newInstance();
        //调用配置文件中类的方法
        method.invoke(object,"hahaha");
    }
}

二 获取泛型的返回类型

先看段代码:

package com.todoming.reflect;
import java.util.ArrayList;
import java.util.List;
public class Generic {
    public static void main(String[] args) throws Exception {
        List<Integer> list = new ArrayList<>();
        list.add(10);
        //通过反射调用 list的add方法
        list.getClass().getMethod("add",Object.class).invoke(list,"hahah");
        System.out.println(list.toString());
    }
}

这里定义了一个只能存入int类型的List 在通过反射调用add方法时缺可以插入一个string类型的值。
这个要从泛型的原理说起:Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。所以java的泛型是一种伪泛型。反射是在运行状态中获取的,所以通过反射调用的时候我们声明的类型已经被擦除了。这个有时候会导致类型转换失败的问题。

可以通过反射的方式获取返回泛型方法的返回类型。
在University类中添加如下方法

public List<String> getList(String name){
        List<String> list = new ArrayList<>();
        list.add(name);
        return list;
    }

获取返回类型

package com.todoming.reflect;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class GetGenericReturn {
    public static void main(String[] args) throws Exception{
        Class cla = Class.forName("com.todoming.reflect.University");
        //这里University类中getList方法
        Method method = cla.getMethod("getList",String.class);
        //获取方法的返回类型对象
        Type returnType = method.getGenericReturnType();
        //判断该type对象能不能转型为ParameterizedType
        if (returnType instanceof ParameterizedType){
            ParameterizedType parameterizedType = (ParameterizedType)returnType;
            //调用getActualTypeArguments得到参数化类型的数组
            Type[] types = parameterizedType.getActualTypeArguments();
            for (Type type:types){
                //转型为Class对象
                Class returnTy = (Class)type;
                System.out.println(returnTy);
            }
        }
    }
}

使用上比较灵活些 不局限与以上这一种写法。关于java泛型的类型擦除有时间研究下。

三、操作数组

Java反射可以对数组进行操作,包括创建一个数组,访问数组中的值,以及得到一个数组的Class对象。

 //创建一个int类型的数组,长度为3
 int[] arr = (int[])Array.newInstance(int.class,10);
 //通过反射的形式,给数组赋值
 for (int i = 0 ;i < arr .length;i++){
       arr .set(arr ,i,i + 2);
 }
//通过反射的形式,得到数组中的值
for (int i = 0 ; i < arr .length;i++){
      System.out.println(Array.get(arr ,i));
}

除以上基本操作外还有些奇怪的用法。

Class clz = Class.forName("[I");
System.out.println(clz.getTypeName());

输出:int[]
forName中的字符串,[表示是数组,I表示是int,float就是F,double就是D 。

Class stringClz = Class.forName("[Ljava.lang.String;");

上面这种用法是获取一个普通对象数组的用法
[表示是数组,L的右边是类名,类型的右边是一个;。
有法基本完了下次看看反射的原理。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • 在经过一次没有准备的面试后,发现自己虽然写了两年的android代码,基础知识却忘的差不多了。这是程序员的大忌,没...
    猿来如痴阅读 2,839评论 3 10
  • 一、Java 简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计...
    子非鱼_t_阅读 4,186评论 1 44
  • 整体Retrofit内容如下: 1、Retrofit解析1之前哨站——理解RESTful 2、Retrofit解析...
    隔壁老李头阅读 4,577评论 2 12
  • 今天起了个大早!对!七点多!〈ps:众人听到一阵嘘嘘,楼猪你怎么可以这么扯淡!七点还叫啥大早!〉 而今天又是个美...
    游尘浮影阅读 172评论 0 1
  • 题记:我想让写作变成清晨唤醒我的鸟鸣,午间小憩的甜梦,傍晚散步的晚风。 其实是不知道我是否能坚持写作,至少希望不会...
    下铺兄弟阅读 649评论 0 51