黑马程序员——JAVA学习笔记——反射机制(下)

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

反射机制的深入应用

反射除了可以取得一个类的完整结构外,还可以调用类中的指定方法或指定属性,并且可以通过反射完成对数组的操作。

1、 通过反射调用类中的方法:

使用Method类完成

  操作步骤:

(1)通过Class 类的getMethod(String name,Class…parameterTypes)方法取得一个Method的对象,并设置次方法操作时所需要的参数类型。

(2)之后可以使用invoke()进行调用。并向方法中传递要设置的参数。

样板代码:定义一个Person类和China接口测试

package org.lzz.heima ;

interface China{  // 定义China接口

       public static final String NATIONAL = "China" ;     // 定义全局常量

       public static final String AUTHOR = "welcome!" ;   // 定义全局常量

       public void sayChina() ;           // 无参的,没有返回值的方法

       public String sayHello(String name,int age) ;      // 定义有两个参数的方法,并返回内容

}

public class Person implements China{

       private String name ;

       private int age ;

       public Person(){  // 无参构造

       }

       public Person(String name){

              this.name = name ;    // 设置name属性

       }

       public Person(String name,int age){

              this(name) ;

              this.age = age ;

       }

       public void sayChina(){     // 覆写方法

              System.out.println( AUTHOR  + NATIONAL) ;

       }

       public String sayHello(String name,int age){

              return name + ",你好!我今年:" + age + "岁了!" ;

       }

       public void setName(String name){

              this.name = name ;

       }

       public void setAge(int age){

              this.age = age ;

       }

       public String getName(){

              return this.name ;

       }

       public int getAge(){

              return this.age ;

       }

};

运用一:调用Person类中的sayChina()方法

public class Test{

       public static void main(String args[]){

              Class<?> c1 = null ;

              try{

                     c1 = Class.forName("org.lzz.heima.Person") ;   // 实例化Class对象

              }catch(Exception e){}

              try{

                     Method  met = c1.getMethod("sayChina") ;   // 找到sayChina()方法

                     met.invoke(c1.newInstance()) ;     // 调用方法

              }catch(Exception e){

                     e.printStackTrace() ;

              }

       }

};

运用二:调用Person类中的sayHello 方法

  此方法中存在两个参数

采用如下格式:Method  met = c1.getMethod("sayHello",String.class,int.class) ;

      String rv = null ;

          rv = (String)met.invoke(c1.newInstance(),"张三",30) ;

 

public class Test{

       public static void main(String args[]){

              Class<?> c1 = null ;

              try{

                     c1 = Class.forName("org.lzz.heima.Person") ;   // 实例化Class对象

              }catch(Exception e){}

              try{

                     Method  met = c1.getMethod("sayHello",String.class,int.class) ;    // 找到sayChina()方法

                     String rv = null ;

                     rv = (String)met.invoke(c1.newInstance(),"张三",30) ;     // 调用方法

                     System.out.println(rv) ;

              }catch(Exception e){

                     e.printStackTrace() ;

              }

       }

};

运用三:调用setter及getter方法

实现步骤:

(1)设置方法名,因为Person类中方法名为:setName(),getName(),setAge(),getAge()

其中属性的的首个字母大写了,所以单独设置一个initStr()方法解决。

(2)调用setter()方法,为满足getMethod()和invoke()方法的使用要求,传入实例化对象、要操作的属性名字、要设置的参数内容以及具体的参数类型。

 

public class Test{

       public static void main(String args[]){

              Class<?> c1 = null ;

              Object obj = null ;

              try{

                     c1 = Class.forName("org.lzz.heima.Person") ;   // 实例化Class对象

              }catch(Exception e){}

              try{

                     obj = c1.newInstance() ;

              }catch(Exception e){}

              setter(obj,"name","张三",String.class) ;       // 调用setter方法

              setter(obj,"age",30,int.class) ;       // 调用setter方法

              System.out.print("姓名:") ;

              getter(obj,"name") ;

              System.out.print("年龄:") ;

              getter(obj,"age");

       }

       /**

              Object obj:要操作的对象

              String att:要操作的属性

              Object value:要设置的属性内容

              Class<?> type:要设置的属性类型

       */

       public static void setter(Object obj,String att,Object value,Class<?> type){

              try{

                     Method met = obj.getClass().getMethod("set"+initStr(att),type) ;    // 得到setter方法

                     met.invoke(obj,value) ;  // 设置setter的内容

              }catch(Exception e){

                     e.printStackTrace() ;

              }

       }

       public static void getter(Object obj,String att){

              try{

                     Method met = obj.getClass().getMethod("get"+initStr(att)) ;    // 得到setter方法

                     System.out.println(met.invoke(obj)) ;   // 调用getter取得内容

              }catch(Exception e){

                     e.printStackTrace() ;

              }

       }

       public static String initStr(String old){  // 将单词的首字母大写

              String str = old.substring(0,1).toUpperCase() + old.substring(1) ;

              return str ;

       }

};

运用四:通过反射操作属性

操作步骤:

(1) 通过Field类操作类中的属性,通过Field类提供的set()和get()方法完成设置和取得属性内容的操作。

(2) 使用Field类中的setAccessibel(true)方法将操作的属性设置成可以被外部访问。(因为Field类中的所有属性全部设置成了私有权限)

 

public class Test{

       public static void main(String args[]) throws Exception{

              Class<?> c1 = null ;

              Object obj = null ;

              c1 = Class.forName("org.lzz.heima.Person") ;   // 实例化Class对象

              obj = c1.newInstance() ;

              Field nameField = null ;

              Field ageField = null ;

              nameField = c1.getDeclaredField("name") ;       // 取得name属性

              ageField = c1.getDeclaredField("age") ;     // 取得name属性

              nameField.setAccessible(true) ;   // 此属性对外部可见

              ageField.setAccessible(true) ;     // 此属性对外部可见

              nameField.set(obj,"张三") ;  // 设置name属性内容

              ageField.set(obj,30) ;                   // 设置age属性内容

              System.out.println("姓名:" + nameField.get(obj)) ;

              System.out.println("--------");

              System.out.println("年龄:" + ageField.get(obj)) ;

       }

};

 

2、 通过反射操作数组:

反射机制不仅可以用在类上,还可以应用在任意的引用数据类型的数据上。

可以同过Class类中的方法取得一个数组的Class对象:

public Class<?>getComponentType()

了解数组类\Array的一些常用方法:

  ||-根据下标去的具体内容:public static Object get(Object  array,int index)throws Illegal ArgumentException,ArrayIndexOutBoundsException

  ||-根据已有的数组类型开辟新的数组对象:Public static Object newInstance(Class<?>componentType,int length)throws NegativeArraySizeException

  ||-修改指定位置的内容;  public static void set(Object array,int index,Object value)throws IllegalArgumentException,ArrayIndexOutOfBoudsException

运用一:取得数组信息并修改数组的内容

import java.lang.reflect.Array ;

public class Test{

       public static void main(String args[]) throws Exception{

              int temp[] = {1,2,3} ;// 声明一整型数组

              Class<?> c = temp.getClass().getComponentType() ;      // 取得数组的Class对象

              System.out.println("类型:" + c.getName()) ;   // 取得数组类型名称

              System.out.println("长度:" + Array.getLength(temp)) ;

              System.out.println("第一个内容:" + Array.get(temp,0)) ;

              Array.set(temp,0,6) ;

              System.out.println("第一个内容:" + Array.get(temp,0)) ;

       }

};

运用二:修改数组的大小

import java.lang.reflect.Array ;

public class Test{

       public static void main(String args[]) throws Exception{

              int temp[] = {1,2,3} ;// 声明一整型数组

              int newTemp[] = (int []) arrayInc(temp,5) ;       // 重新开辟空间5

              print(newTemp) ;

              System.out.println("\n-------------------------") ;

              String t[] = {"lzz","cscd","csdnjava"} ;

              String nt[] = (String [])arrayInc(t,8) ;

              print(nt) ;

       }

       public static Object arrayInc(Object obj,int len){

              Class<?> c = obj.getClass() ;

              Class<?> arr = c.getComponentType() ;    // 得到数组的

              Object newO = Array.newInstance(arr,len) ;     // 开辟新的大小

              int co = Array.getLength(obj) ;

              System.arraycopy(obj,0,newO,0,co) ;  // 拷贝内容

              return newO ;

       }

       public static void print(Object obj){     // 数组输出

              Class<?> c = obj.getClass() ;

              if(!c.isArray()){    // 判断是否是数组

                     return;

              }

              Class<?> arr = c.getComponentType() ;

              System.out.println(arr.getName()+"数组的长度是:" + Array.getLength(obj)) ;  // 输出数组信息

              for(int i=0;i<Array.getLength(obj);i++){

                     System.out.print(Array.get(obj,i) + "、") ;  // 通过Array输出

              }

       }

};

 

 

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值