Java反射的小故事:

首先定义一个Java类

 package com.xiaoysec.test;

 public class Person {
private String name;
private String sex;
private int id; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public Person(String name, String sex, int id) {
this.name = name;
this.sex = sex;
this.id = id;
}
private void show(){
System.out.println("name is:"+this.name);
System.out.println("sex is:"+this.sex);
System.out.println("id is:"+this.id);
}
public static void main(String[] args){
System.out.println(args[0]);
}
}

在类中定义了一些方法,尤其注意的是方法的访问权限,show()方法被定义为了私有方法,以前上课的时候只是说private修饰的方法或属性只能在类的内部进行访问,那么这句话有没有问题呢?

 package com.xiaoysec.test;

 import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import org.junit.Test; public class Classtest {
private String simplename; @Test
public void test() { try {
Class c = Class.forName("com.xiaoysec.test.Person");
Constructor constructor = c.getConstructor(new Class[] {
String.class, String.class, int.class });
Person p = (Person) constructor.newInstance("xiaoysec", "sex", 19);
Method m = c.getDeclaredMethod("show", null); // 获取的是private权限的show方法
m.setAccessible(true); // 强行打开访问权限 使用发射可以访问private方法
// 面试的时候如果被问及private是否可以被访问应该 回答
// 普通的方式只能在类的内部访问 而通过反射可以访问private
m.invoke(p, null);
System.out.println(c.getName());
System.out.println("-------------");
Field f = c.getDeclaredField("name");
f.setAccessible(true);
Class fieldtype = f.getType();
System.out.println(fieldtype);
Object o = f.get(p);
System.out.println(o.getClass()); // 此处返回的是class java.lang.String
System.out.println(o);
System.out.println("--------------");
Method mainmethod = c.getMethod("main", String[].class); // main方法的反射
// mainmethod.invoke(p, new String[]{"xiaoysec"});//argument type
// mismatch
mainmethod.invoke(p, (Object) new String[] { "xiaoysec" });
// mainmethod.invoke(p,new Object[]{new String[]{"xiaoysec"}});
// //此方法也是对的
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }

请注意setAccessible(true)这点,通过设置,就可以访问private修饰的方法了。

另外在上面的代码中值得一提的是main方法的反射

public static void main(String[] args)

这个大家都不陌生,main方法接收一个String数组,在反射中开始时我写的是mainmethod.invoke(p, new String[]{"xiaoysec"});//argument type mismatch提示参数匹配的错误

解决的方法是这样的

 mainmethod.invoke(p, (Object) new String[] { "xiaoysec" });
//或者 mainmethod.invoke(p,new Object[]{new String[]{"xiaoysec"}});

为什么呢?

大致可以这样理解 ,当遇到数组类型的参数时 会进行拆分,例如str[0],str[1]...并将拆分后的参数作为方法的实参这样的话就匹配不到合适的参数了当然反射也就失败了

而方法一(Object) 就是故意的转型让方法认为传入的不是数组

方法二 大致的意思就是 经过拆分后获取到第一个String数组作为方法的实参 这样就符合了main方法接收一个String数组作为实参的条件

下面再来看看反射和泛型的基情:

 package com.xiaoysec.reflecttest;

 import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator; import org.junit.Test; public class Reflecttest {
@Test
public void test() {
ArrayList<String> list = new ArrayList<String>();
list.add("xiaoysec");
list.add("B12040423");
Iterator it = list.iterator();
while (it.hasNext()) {
String str = (String) it.next();
if (str.equals("xiaoysec")) {
str = "xiaoy";
// list.add("nanjing"); 在iterator作用范围内不能改变集合中的元素
}
System.out.println(str);
} }
/**
* 下面的測試方法證明了java中的泛型只是针对编译时有效
* 通过反射可以绕过泛型的限制
*/
@Test
public void test2() {
ArrayList<String> list2 = new ArrayList<String>();
list2.add("XIAOYSEC");
list2.add("12040423");
for(String str:list2){
System.out.println(str);
}
System.out.println("-----------------");
try {
Class c = list2.getClass();
Method m = c.getMethod("add", Object.class); // public boolean add(E e)
m.invoke(list2, 12); //传入的参数是12 int类型而非String类型
Iterator it = list2.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }

可以看到通过反射可以绕过泛型的限制,也就是说Java泛型是在编译阶段起作用在运行时不会产生限制。

Java反射的小故事的更多相关文章

  1. Java反射机制小例子

    package com.wjy.main; import java.io.Console; import java.lang.reflect.Constructor; import java.lang ...

  2. 【动态页面】(二)Java反射

    Java的反射机制是Java语言非常重要的一个特性.先从Sun官网上看一下官网是怎样定义反射机制的. 大致翻译一下,翻译的可能不是非常准确. 反射(Reflection)是Java程序设计语言的一个特 ...

  3. java反射(基础了解)

    package cn.itcast_01; /** *Person类 */ public class Person {    /** 姓名 */    private String name;     ...

  4. java 反射的应用 以及通过反射 用到的工厂模式

    java反射详解 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案 ...

  5. 反射——Java反射机制

    反射概述 什么是反射? ①   反射的概念是由Smith在1982年首次提出的,主要指程序可以访问.检测和修改它本身状态或行为的一种能力. ②   JAVA反射机制是在运行状态中,对应任意一个类,都能 ...

  6. java反射的基础学习代码

    java反射的学习,好多东西不太理解,主要分析了constructor,method,field,数组和调用main函数等反射的多个方面小例子. 主要的练习类 package javaAdvanced ...

  7. Java 反射练习

    已同步更新至个人blog:http://dxjia.cn/2015/08/java-reflect/ 引用baidubaike上对JAVA反射的说明,如下:JAVA反射机制是在运行状态中,对于任意一个 ...

  8. Java反射机制的学习

    Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调 ...

  9. JAVA反射机制—学习总结

    最近收到很多关于Java反射机制的问题留言,其实Java反射机制技术方面没有太多难点,或许是大家在学习过程中遗漏了细小知识点,导致一些问题无法彻底理解,现在我们简单的总结一下,加深印象.什么是反射机制 ...

随机推荐

  1. Java程序员快速入门Go语言

    这篇文章帮助Java程序员快速入门Go语言. 转载至 开源中国社区. http://www.oschina.net 本文将以一个有代表性的例子为开始,以此让Java程序员对Go语言有个初步认识,随后将 ...

  2. poj1651 最优矩阵乘法动态规划解题

    题目描述: 有若干个矩阵{Ai},元素都为整数且已知矩阵大小. 如果要计算所有矩阵的乘积A1 * A2 * A3 .. Am,最少要多少次整数乘法? 输入 第一行一个整数n(n <= 100), ...

  3. openstack 开发step-by-step

    Set up your Open Stack There are several ways to deploy openstack, Devstack is easily for developer ...

  4. Java-----Excel转HTML

    尽管是转别人的(忘了哪转过来的了),但此处标为原创不是为了提高訪问量,也不是为了其它.仅仅是纯粹的认为有实际用途.希望能给很多其它有此需求的人看到并能帮到他们就足够了 所需jar包:jxl.jar p ...

  5. 前端新人学习笔记-------html/css/js基础知识点

    即将毕业的软件工程大学生一枚,秋季招聘应聘的是Android,今年来到公司实习,要求做前端开发,所以一切只有现学,现在根据视频来学习,然后开这个博客记录一下自己的学习过程,废话不多说,开写. 4月6日 ...

  6. Android Studio插件之FindBugs

    1.安装方法: AndroidStudio->Settigns->Plugins->Browse repositories->search "findBUgs-IDE ...

  7. Oracle中的Truncate和Delete语句

    Oracle中的Truncate和Delete语句   首先讲一下,truncate命令:   语法:TRUNCATE  TABLE  table; 表格里的数据被清空,存储空间被释放. 运行后会自动 ...

  8. apache hide index.php

    <Directory "D:/usr/local/www">    AllowOverride all    Options +FollowSymLinks +SymL ...

  9. DSP的cache一般在何时会生效,防止在cache使用造成数据不一致

    在使用DSP的cache使能所有的ddr操作时,发现如果只是写操作,根据cache的机制,如果没有在了L1级hit,则直接使用write buffer来完成写操作. 假如hit的话,那之前一定发生过读 ...

  10. codeforces 510E. Fox And Dinner 网络流

    题目链接 给出n个人, 以及每个人的值, 要求他们坐在一些桌子上面, 每个桌子如果有人坐, 就必须做3个人以上. 并且相邻的两个人的值加起来必须是素数.每个人的值都>=2. 由大于等于2这个条件 ...