黑马程序员----反射
2015-09-13 21:28
399 查看
第一部分
基础知识篇:
反射的定义:反射就是把java类中的各种成分映射成相应的java类,获取的变量,方法,构造方法,修饰符等这些信息就用相应的java类表示
它们是Filed,Method,Constructor,Package等
发射的基石:Class ,java程序中各个java类属于同一事物,描述这一类事物的类名就是Class
可以对比前面的学习 众多的人可以用Person类描叙,众多的java类可以用Class描述
其实Class类的对象就是一类字节码,我么可以通过Class类的方法获得加载到内存中的字节码的构造方法,
类的名称,类的所属包,类的成员变量,父类等
获取字节码对象的方法:
(1) 通过点运算符获取:比如我们已经导入一个person()类到内存,现在我们可以通过一个对象p1.getClass()方法获取
(2) 通过指定完整的类名获取:例如class.forName( “java.lang.String”)
(3) 直接在源程序中写出 例如我们需要Data类 可以通过Class cls =Data.class获取 例如System.class,编译器可以自动识别
九个预定义class类型:8基础数据类型class数据对象:boolean,byte,char,short,int,,long,float,double和void
第二部分:反射的应用举例
Constructor可获取全部构造方法或者其中一个构造方法
例如:String str = new String(new stringBuffer("abc"))可以通过反射方法得到相同结果
//得到一个Constructor类的对象cons,cons对象可以得到这个类的一些属性(getDeclearingClass()得到所属的类,getModifier()得到修饰符,)这里举例
//newInstence()方法,下面用此方法建立对象
Constructor cons = ClassforName(“java.lang.String”).getConstructor(StringBffer.class);
//上面一条语句StringBuffer表示选择哪一个构造方法,这一条语句表示用这个构造方法时候还在传StringBuffer的对象进去
//cons前面的强转是因为编译的时候不知道cons是什么类型的构造方法
String str = (String)cons.newInstance(new StringBuffer("abc"));
类的成员变量Filed类,获取类的某一字段,比如成员变量
先建立一个类
class Filed
{
public int x=3;
private int y=5;
public Filed(int x,int y)
{
this.x=x;
this.y=y;
}
}
Filed f=new Filed(3,5)
Filed filedx=f.getClass().getFiled("x")
//现在获得的filedx并不是3,因为他是一个类的字段,并不是一个具体的值
//可以通过get方法获取某一个对象上的值
System.out.println(filedx.get(f));
注意:
当变量为私有的时候 有两步不一样
//gerDeclearFiled()设置可见
Filed filedy=f.getClass().getDeclearedFiled("y")
//setAccessable(ture)设置可见
filedx.setAccessable(ture);
System.out.println(filedy.get(f));
Method类:获取某个类的成员方法
在String的各个对象中 任意一个字符串对象都可以调用CharAt方法,现在可以通过反射的方式由任意一个对象得到此方法
例如:String str = “abc” str.charAt(1)
//指定方法名称和方法参数类型
Method methodcharat = String.class.getMethod("charAt",int.class)
//返回的方法methodcharat,再用方法作用于对象,invoke表示函数的调用动作
System.out.println(methodcharat.invoke(str,1))
用反射方式调用某个类的main方法
例如:
class demo
{
public static void main(String [ ] args)
{
for(String arg: args)
{
System.out.println(arg);
}
}
}
在另一个类中调用的方法有
demo.main(new String[ ] { “111”,"222","333"} )
但是当一些场合下 不知道类的名字 无法通过类名调用,这时可以用反射方法解决
//将startname给主函数参数的args[0]
String startname = args[0];
//通过forName获得主函数
Method method = Class.forName(startname).getMethod("main",String [ ] .class);
将三个元素打包成一个数组
method.invoke(null,new Object[ ] (new String[ ] { “111”,"222","333"}));
数组的反射应用
如果是一个数组,则依次打印数组的每一个元素 如果是单个字符串直接打印
class demo
{
public static void printss(Object obj)
{
//得到字节码
Class example = obj.getClass();
//通过字节码判断是否是数组
if(example.isArray())
{
int len = Array.getLenth(obj);
for(int x=0;x<len;x++)
{
System.out.println(Array.get(obj,x));
}
}
else
{
System.out.println(obj);
}
}
public static void main(String [ ] args)
{
//主函数调用
String [ ] ass = {"aaa","bbb","ccc"};
String bss = "aaabbbccc" ;
printss(ass);
printss(bss);
}
}
第三部分:练习
要求:编写程序,将符合要求的所有对象字符串中的指定字符替换成相应字符
public class filetest
{
String s1 ="ball";
String s2 ="basketball";
String s3 ="itheima";
public String toString()
{
return(s1+":"+s2+":"+"s3");
}
}
import java.text.DateFormat.Field;
class reflect
{
publicstaticvoid
main(String [] args)throws Exception
{
filetest pt1 = new filetest();
changeValue(pt1);
System.out.print(pt1);
}
publicstaticvoid
changeValue(Object obj)throws Exception
{
java.lang.reflect.Field[] fil = obj.getClass().getFields();
for(java.lang.reflect.Field field : fil )
{
if(field.getType() == String.class)
{
String oldvalue = (String)field.get(obj);
//将b替换成a
String newvalue = oldvalue.replace('b','a');
fil.set(obj,newvalue);
}
}
}
}
第四部分:总结
通过前面的学习,反射的应用可以归纳为
(1)修改配置文件,可以通过一个类的其中一个对象 修改所有的对象属性
(2)当程序开发时候,无法知道一些类,不能直接new对象,可以通过反射的方法先写好项目框架
基础知识篇:
反射的定义:反射就是把java类中的各种成分映射成相应的java类,获取的变量,方法,构造方法,修饰符等这些信息就用相应的java类表示
它们是Filed,Method,Constructor,Package等
发射的基石:Class ,java程序中各个java类属于同一事物,描述这一类事物的类名就是Class
可以对比前面的学习 众多的人可以用Person类描叙,众多的java类可以用Class描述
其实Class类的对象就是一类字节码,我么可以通过Class类的方法获得加载到内存中的字节码的构造方法,
类的名称,类的所属包,类的成员变量,父类等
获取字节码对象的方法:
(1) 通过点运算符获取:比如我们已经导入一个person()类到内存,现在我们可以通过一个对象p1.getClass()方法获取
(2) 通过指定完整的类名获取:例如class.forName( “java.lang.String”)
(3) 直接在源程序中写出 例如我们需要Data类 可以通过Class cls =Data.class获取 例如System.class,编译器可以自动识别
九个预定义class类型:8基础数据类型class数据对象:boolean,byte,char,short,int,,long,float,double和void
第二部分:反射的应用举例
Constructor可获取全部构造方法或者其中一个构造方法
例如:String str = new String(new stringBuffer("abc"))可以通过反射方法得到相同结果
//得到一个Constructor类的对象cons,cons对象可以得到这个类的一些属性(getDeclearingClass()得到所属的类,getModifier()得到修饰符,)这里举例
//newInstence()方法,下面用此方法建立对象
Constructor cons = ClassforName(“java.lang.String”).getConstructor(StringBffer.class);
//上面一条语句StringBuffer表示选择哪一个构造方法,这一条语句表示用这个构造方法时候还在传StringBuffer的对象进去
//cons前面的强转是因为编译的时候不知道cons是什么类型的构造方法
String str = (String)cons.newInstance(new StringBuffer("abc"));
类的成员变量Filed类,获取类的某一字段,比如成员变量
先建立一个类
class Filed
{
public int x=3;
private int y=5;
public Filed(int x,int y)
{
this.x=x;
this.y=y;
}
}
Filed f=new Filed(3,5)
Filed filedx=f.getClass().getFiled("x")
//现在获得的filedx并不是3,因为他是一个类的字段,并不是一个具体的值
//可以通过get方法获取某一个对象上的值
System.out.println(filedx.get(f));
注意:
当变量为私有的时候 有两步不一样
//gerDeclearFiled()设置可见
Filed filedy=f.getClass().getDeclearedFiled("y")
//setAccessable(ture)设置可见
filedx.setAccessable(ture);
System.out.println(filedy.get(f));
Method类:获取某个类的成员方法
在String的各个对象中 任意一个字符串对象都可以调用CharAt方法,现在可以通过反射的方式由任意一个对象得到此方法
例如:String str = “abc” str.charAt(1)
//指定方法名称和方法参数类型
Method methodcharat = String.class.getMethod("charAt",int.class)
//返回的方法methodcharat,再用方法作用于对象,invoke表示函数的调用动作
System.out.println(methodcharat.invoke(str,1))
用反射方式调用某个类的main方法
例如:
class demo
{
public static void main(String [ ] args)
{
for(String arg: args)
{
System.out.println(arg);
}
}
}
在另一个类中调用的方法有
demo.main(new String[ ] { “111”,"222","333"} )
但是当一些场合下 不知道类的名字 无法通过类名调用,这时可以用反射方法解决
//将startname给主函数参数的args[0]
String startname = args[0];
//通过forName获得主函数
Method method = Class.forName(startname).getMethod("main",String [ ] .class);
将三个元素打包成一个数组
method.invoke(null,new Object[ ] (new String[ ] { “111”,"222","333"}));
数组的反射应用
如果是一个数组,则依次打印数组的每一个元素 如果是单个字符串直接打印
class demo
{
public static void printss(Object obj)
{
//得到字节码
Class example = obj.getClass();
//通过字节码判断是否是数组
if(example.isArray())
{
int len = Array.getLenth(obj);
for(int x=0;x<len;x++)
{
System.out.println(Array.get(obj,x));
}
}
else
{
System.out.println(obj);
}
}
public static void main(String [ ] args)
{
//主函数调用
String [ ] ass = {"aaa","bbb","ccc"};
String bss = "aaabbbccc" ;
printss(ass);
printss(bss);
}
}
第三部分:练习
要求:编写程序,将符合要求的所有对象字符串中的指定字符替换成相应字符
public class filetest
{
String s1 ="ball";
String s2 ="basketball";
String s3 ="itheima";
public String toString()
{
return(s1+":"+s2+":"+"s3");
}
}
import java.text.DateFormat.Field;
class reflect
{
publicstaticvoid
main(String [] args)throws Exception
{
filetest pt1 = new filetest();
changeValue(pt1);
System.out.print(pt1);
}
publicstaticvoid
changeValue(Object obj)throws Exception
{
java.lang.reflect.Field[] fil = obj.getClass().getFields();
for(java.lang.reflect.Field field : fil )
{
if(field.getType() == String.class)
{
String oldvalue = (String)field.get(obj);
//将b替换成a
String newvalue = oldvalue.replace('b','a');
fil.set(obj,newvalue);
}
}
}
}
第四部分:总结
通过前面的学习,反射的应用可以归纳为
(1)修改配置文件,可以通过一个类的其中一个对象 修改所有的对象属性
(2)当程序开发时候,无法知道一些类,不能直接new对象,可以通过反射的方法先写好项目框架
相关文章推荐
- Java反射随记
- AS3中的反射(速记) 分析
- C# 反射(Reflection)的用处分析
- C#通过反射创建自定义泛型
- 通俗易懂的C#之反射教程
- C#根据反射和特性实现ORM映射实例分析
- 深入反射生成数组的详解
- C#利用反射来判断对象是否包含某个属性的实现方法
- C#利用反射技术实现去掉按钮选中时的边框效果
- C#泛型和反射实例解析
- C# Dynamic关键字之:dynamic为什么比反射快的详解
- 传智播客学习之java 反射
- Java 反射之私有字段和方法详细介绍
- php使用反射插入对象示例分享
- java反射使用示例分享
- java利用反射实现动态代理示例
- 用户控件(ASCX)向网页(ASPX)传值使用反射实现
- 基于Java回顾之反射的使用分析
- c#反射调用方法示例
- C#通过反射获取当前工程中所有窗体并打开的方法