JAVA 反射整理

1.反射含义是什么?

Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。你仅仅传一个类的全包名路径,就能通过反射,来获取对应的类实例,我们一般会用Class类,来调用这个被反射的Objcet类下的,构造方法,属性,或方法等,反射在一些开源框架里用的非常之多,Spring,Struts,Hibnerate,MyBatics都有它的影子。

一句话就是:java 动态获取的类的方法属性以及动态调用对象的方法的功能叫做反射。

两种不同的状态:

静态编译: 在编译时确定类型,绑定对象,即通过。

动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。

2.反射机制的优点与缺点?

优点:

(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。

(2)与Java动态编译相结合,可以实现无比强大的功能

缺点:

(1)使用反射的性能较低

(2)使用反射相对来说不安全

(3)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性

2.反射的用法和示例?

Java反射所需要的类并不多,主要有java.lang.Class类和java.lang.reflect包中的Field、Constructor、Method、Array类。

注意:Class类是Java反射的起源,针对任何一个你想探勘的类,只有先为它产生一个Class类的对象,接下来才能通过Class对象获取其他想要的信息。

java反射可以获取一下信息:Class 对象、类名、修饰符、包信息、父类、实现的接口、构造器、方法、变量、注解。

来来来,让我们创建一个对象,然后在分别尝试使用它的各种方法,本文不作详细的解释。
Person Class

public class Person implements Action {
    private String name;
    private int age;
    private String head;
    protected List<String> stringList = new ArrayList<>();
    private String privateString = null;

    public Person(String name) {
        this.name = name;
    }

    public Person(String name, int age, String head) {
        this.name = name;
        this.age = age;
        this.head = head;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("打印参数:" + name);
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getHead() {
        return head;
    }

    public void setHead(String head) {
        this.head = head;
    }

    @Override
    public String toString() {
        return "Person{" +
                       "name='" + name + '\'' +
                       ", age=" + age +
                       ", head='" + head + '\'' +
                       '}';
    }


    public Person(String name, String privateString) {
        this.name = name;
        this.privateString = privateString;
    }


    public void setPrivateString(String privateString) {
        this.privateString = privateString;
    }

    private String getPrivateString() {
        return this.privateString;
    }


    public List<String> getStringList() {
        return this.stringList;
    }

    public void setStringList(List<String> stringList) {
        this.stringList = stringList;
    }

    @Override
    public void run() {

    }

    @Override
    public void jump() {

    }

    @Override
    public void rotate() {

    }

}

Action 接口类
Person 子类 纯属测试一个方法

public class Hero extends Person {
public Hero(String name, int age, String head) {
    super(name, age, head);
}
}

//获取Class对象
' Class className = Class.forName("com.java.study.reflect.Person");'
//即获取类名 又获取包名
' System.out.println("Name:" + className.getName());'
//仅仅获取类名 不获取包名
' System.out.println("SimpleName:" + className.getSimpleName());'
//获取类的 Modifiers 修饰符
int modifiers = className.getModifiers();
System.out.println("类是否为抽象的:" + Modifier.isAbstract(modifiers));
System.out.println("是否用Final修饰:" + Modifier.isFinal(modifiers));
System.out.println("isInterface:" + Modifier.isInterface(modifiers));
System.out.println("isNative:" + Modifier.isNative(modifiers));
System.out.println("isPrivate:" + Modifier.isPrivate(modifiers));
System.out.println("isProtected:" + Modifier.isProtected(modifiers));
System.out.println("isPublic:" + Modifier.isPublic(modifiers));
System.out.println("isStatic:" + Modifier.isStatic(modifiers));
System.out.println("isStrict:" + Modifier.isStrict(modifiers));
System.out.println("isSynchronized:" + Modifier.isSynchronized(modifiers));
System.out.println("isTransient:" + Modifier.isTransient(modifiers));
System.out.println("isVolatile:" + Modifier.isVolatile(modifiers));
//Hero Class
' Class hero = Class.forName("com.java.study.reflect.Hero");'

//获取包的信息
'System.out.println("包名:" + hero.getName());'
//获取父类信息 (然后可以获取父类的信息)
' System.out.println("Class 对象你可以访问类的父类:"+hero.getSuperclass().getName());' //类的接口
Class[] interfaces = className.getInterfaces();
if (interfaces.length > 0) {
System.out.println("集成接口的名字:" + interfaces[0].getName());
}

//根据 Class 对象来获取 Constructor 类
Constructor[] constructors = className.getConstructors();
if (constructors.length > 0) {
Class[] parameterTypes = constructors[0].getParameterTypes();
System.out.println("构造参数数组:" + parameterTypes[0]);
}
''
//采用反射返回一个字段的值
Field[] fields = className.getFields();
Person person = new Person("小明");
Field privateStringField = Person.class.getDeclaredField("name");
//setAccessible()方法会关闭指定类 Field 实例的反射访问检查,这行代码执行之后不论是私有的、受保护的以及包访问的作用域,
// 你都可以在任何地方访问,即使你不在他的访问权限作用域之内。但是你如果你用一般代码来访问这些不在你权限作用域之内的代码依然是不可以的,
// 在编译的时候就会报错。
privateStringField.setAccessible(true);
String fieldValue = (String) privateStringField.get(person);
System.out.println("fieldValue = " + fieldValue);

        //根据字段 返回一个私有方法
        Person person2 = new Person("小明", "The Private Value");
        Method privateStringMethod = Person.class.getDeclaredMethod("getPrivateString", null);
        privateStringMethod.setAccessible(true);
        String returnValue = (String) privateStringMethod.invoke(person2, null);
        System.out.println("returnValue = " + returnValue);

        //反射中的类型
        Method method = Person.class.getMethod("getStringList", null);
        Type returnType = method.getGenericReturnType();
        if (returnType instanceof ParameterizedType) {
            ParameterizedType type = (ParameterizedType) returnType;
            Type[] typeArgument = type.getActualTypeArguments();
            for (Type typeItem : typeArgument) {
                Class typeArgClass = (Class) typeItem;
                System.out.println("typeArgClass = " + typeArgClass);
            }
        }

        Method method2 = Person.class.getMethod("setStringList", List.class);
        Type[] genericParameterTypes = method2.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            if (genericParameterType instanceof ParameterizedType) {
                ParameterizedType aType = (ParameterizedType) genericParameterType;
                Type[] parameterArgTypes = aType.getActualTypeArguments();
                for (Type parameterArgType : parameterArgTypes) {
                    Class parameterArgClass = (Class) parameterArgType;
                    System.out.println("parameterArgClass = " + parameterArgClass);
                }
            }
        }

'''

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

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,577评论 18 399
  • 1. 了解 Java 中的反射 1.1 什么是 Java 的反射 Java 反射是可以让我们在运行时获取类的函数、...
    Ten_Minutes阅读 530评论 0 4
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,066评论 0 62
  • 一、Java 反射机制 参考了许多博文,总结了以下个人观点,若有不妥还望指正: Java 反射机制在程序运行时,对...
    野梦M阅读 462评论 0 1
  • 几天光看别个的字了,感觉好难学习!都不敢完成作业了
    一帘幽幽梦阅读 200评论 7 11