黑马程序员---java中的反射
来源:互联网 发布:淘宝禁止好评返现规则 编辑:程序博客网 时间:2024/04/28 07:12
反射
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
反射就是把java中各种成分映射成相应的java类.
反射的基石 --Class类
1.获得Class类对象通常有以下3中方式:
1.使用Class类的forName(String clazzName)静态方法.该方法.该方法需要传入字符串参数,该字符串参数值是某个类的全限定类名.
2.调用某个对象的getClass()方法,该方法是java.lang.Object类中的一个方法,所以所有的java对象都可以调用该方法,方法方法返回该对象所属类对应的Class对象.
3.调用某个类的Class属性来获取该类对应的Class对象.例如:Person.class将会返回Person类对应的Class对象.
演示代码如下:
package cn.itheima;
/**
* 该程序主要演示获取Class对象的方法.
* 1.使用Class类的forName(String clazzName)静态方法.
2.调用某个对象的getClass()方法.
3.调用某个类的Class属性来获取该类对应的Class对象.
*/
public class GetClass {
public static void main(String[] args) throws ClassNotFoundException {
/**
* 1.通过Class类的静态方法获取类名
*/
Class c=Class.forName("java.lang.String");
System.out.println(c.getName());
Class c2=Class.forName("cn.itheima.GetClass");
System.out.println(c2.getName());
/**
* 2.通过调用对象的getClass()方法,获取类名
*/
GetClass g=new GetClass();
Class c3=g.getClass();
System.out.println(c3.getName());
String str=new String();
Class c4=str.getClass();
System.out.println(c4.getName());
/**
* 3.通过某个类的class属性获取类名
*/
Class c5=String.class;
System.out.println(c5.getName());
Class c6=GetClass.class;
System.out.println(c6.getName());
}
}
2.构造器的反射(Constructor 类)
1.获取某类的构造方法
/**
* 获取本类的构造器方法
*/
Constructor con1=c6.getConstructor(String.class,int.class,int.class);
System.out.println(con1.toString());
Constructor con2=c6.getConstructor(null);
System.out.println(con2.toGenericString());
2.利用获取的构造方法创建一个实例
/**
* 通过获取到了构造器创建一个实例对象,并调用该对象的方法
*/
GetClass gc=(GetClass)con1.newInstance("reflect",13,14);
System.out.println(gc.toString());
3.成员变量的反射(Field 类)
为了演示,我先定义一个Person类.该类的定义见代码:
package cn.itheima;
public class Person {
/*
* 为了便于演示对属性的操作,因此我就直接
* 为属性赋予初始值
*/
private String name="王震阳";
private int age=23;
private String sex="man";
private int salary=0;
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex
+ ", salary=" + salary + "]";
}
public Person() {
super();
}
public Person(String name, int age, String sex, int salary) {
super();
this.name = name;
this.age = age;
this.sex = sex;
this.salary = salary;
}
}
3.1获取Person类中的属性值
/**
* 获取Person类的成员变量
*/
Class c7 = Class.forName("cn.itheima.Person");
Field f1 = c7.getDeclaredField("name");
/**
* 因为name是私有的,如果直接调用getName()方法则会抛出NoSuchFieldException异常
* 因此对于私有变量,应该采用"暴力"获取的方法.
* 在这里只演示"暴力"获取方法
*/
//System.out.println(f1.getName());//无法访问private变量
f1.setAccessible(true);
System.out.println(f1.get(new Person()));
Field f2=c7.getDeclaredField("age");
f2.setAccessible(true);
System.out.println(f2.get(new Person()));
3.2修改Person类中的属性值
/**
* 修改成员变量属性
*/
Person p1=new Person();
Class c8=Class.forName("cn.itheima.Person");
Field f3=c8.getDeclaredField("name");
f3.setAccessible(true);
System.out.println(f3.get(p1));
f3.set(p1, (String)"王五");
System.out.println(f3.get(p1));
3.3综合练习,修改属性中所有指定字母
为了完成该练习,首先在Person类中增加以下属性:
private String str1="hiema1";
private String str2="heima2";
private String str3="hiema3";
private String str4="hiema4";
要求:将str1到str4属性值中的”heima”修改为”黑马”.
Person p2=new Person();
Class c9=p2.getClass();
Field[] fields=c9.getDeclaredFields();
//遍历所有属性
for(int i=0;i<fields.length;i++){
fields[i].setAccessible(true);
System.out.println(fields[i].get(p2));
}
//循环茶查找符合要求的属性,并进行修改
for(int i=0;i<fields.length;i++){
fields[i].setAccessible(true);
if(fields[i].getType()==String.class)
{
String temp=(String)fields[i].get(p2);
temp=temp.replace("heima", "黑马");
fields[i].set(p2, temp);
}
}
//再次遍历,为了和修改前后对比
for(int i=0;i<fields.length;i++){
fields[i].setAccessible(true);
System.out.println(fields[i].get(p2));
}
修改前:输出结果
王震阳
23
man
0
heima1
heima2
heima3
heima4
修改后结果:
王震阳
23
man
0
黑马1
黑马2
黑马3
黑马4
4.成员方法的反射(Method类)
1.基本参数类型
Class c10=String.class;//获取String类类型
//获取String类指定的方法
Method m1=c10.getMethod("charAt", int.class);
//调用获取到的方法,作用于"String"字符串,获取第二个脚标位置的字符
//此处如果invoke的第一个参数为null,那么说明该方法为静态的方法
char ch=(char)m1.invoke("string", 2);
System.out.println(ch);
输出结果:s
2.可变参数类型
Person p3=new Person();
Class c11=p3.getClass();
String[] strs={"123","23","wert","wert"};
Method m2=c11.getMethod("show", String[].class);
String[] strs2={"12","23","34"};
//在这个函数的第二个参数,接受的是一个Object对象,因刺激必须把一个数组//强制装换为Object对象
m2.invoke(p3, (Object)strs2);
5.数组的反射
具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象
代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class
基本类型的一维数组可以被当做Object类型使用,不能当成Object[]类型使用,非基本数据类型都可以.
Arrays.asList()方法处理int[]和String[]时的差异
Array工具类用于完成对数组的反射操作.
定义一个打印数组函数
private static void printArray(Object obj) {
if(obj.getClass().isArray()){
for(int i=0;i<Array.getLength(obj);i++){
System.out.println(Array.get(obj, i));
}
}else{
System.out.println(obj);
}
}
在main方法中测试该函数
int[] a={1,2,3,4};
String[] b={"hei","ma","wo","lai","le"};
printArray(a);
printArray(b);
printArray("heima");
运行结果:
1
2
3
4
hei
ma
wo
lai
le
heima
- 黑马程序员-JAVA中的反射
- 黑马程序员--java中的反射。
- 黑马程序员---java中的反射
- 黑马程序员-Java中的反射
- 【黑马程序员】java中的反射机制
- 黑马程序员 java中的反射技术理解
- 黑马程序员—Java中的反射机制
- 黑马程序员——Java中的反射
- 黑马程序员——java中的反射
- 黑马程序员——java中的反射
- 黑马程序员——java中的反射
- 黑马程序员---java反射及反射中的疑惑
- 黑马程序员,黑马论坛 ------JAVA中的反射机制
- 黑马程序员--java 反射
- 黑马程序员--Java反射
- 黑马程序员-java-反射
- 黑马程序员--java反射
- 黑马程序员-Java反射
- VC++改造轮子(二)WindowsAPI多线程编程Thread
- Jquery中LigerUi框架的GRID控件,汇总的使用实例!
- reactor和proactor模式
- vc6的窗口菜单的使用总结
- OpenSSL build for i386、armv6、armv7、armv7s
- 黑马程序员---java中的反射
- Installing Precise (12.04.1) using netboot for Calxeda ECX-1000 (Highbank)
- 获取最大相同子串
- 对段、页、块、扇区的理解
- 禁止和恢复使用Windows身份验证方式登录SQL Server 2000
- Yii Framework 开发教程(37) Zii组件-Dialog示例
- 1041:Computer Transformation
- Yii Framework 开发教程(38) Zii组件-ProgressBar示例
- WPF-DataGrid 绑定数据源