疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java学习笔记反射进一步研究


 

      这里来用反射来调用类中属性和方法

  1.通过反射来调用类中的方法

  步骤

  1.通过Class类的getMethod()方法取得一个Method对象,并设置参数类型

  2.之后使用invoke进行调用,并传参

  interface China{

  public static final String NATIONAL= "china" ;

  public static final String AUTHOR= "like" ;

  public void sayChina();

  public String sayhello(String name, int age);

  }

  public class Person implements China{

  private String name;

  private int age ;

  public String getName() {

  return name ;

  }

  public void setName(String name) {

  this .name = name;

  }

  public int getAge() {

  return age ;

  }

  public void setAge(int age) {

  this .age = age;

  }

  public Person() { //无参构造,好反射

  }

  public Person(String name, int age) {

  this .name = name;

  this .age = age;

  }

  public void sayChina() {

  System. out .println("作者" + AUTHOR+ "国籍"+ NATIONAL );

  }

  public String sayhello(String name, int age) {

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

  }

  }

  package fstest;

  import java.lang.reflect.Method;

  public class InvokeSayChinaDemo {

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

  Class c=Class. forName( "fstest.Person");

  Method m=c.getMethod( "sayChina" );//此方法没有参数

  m.invoke(c.newInstance()); //调用方法,必须传递对象实例

  }

  }

  结果:

  作者like国籍china

  2.调用person类的sayhello()方法

  public class InvokeSayChinaDemo {

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

  Class c=Class. forName( "fstest.Person");

  Method m=c.getMethod("sayhello" ,String. class, int. class); //传参

  String str=(String) m.invoke(c.newInstance(), "like" ,20);//传递参数

  System. out .println(str);

  }

  }

  结果:

  like,你好,我今年20岁了

  3.反射来调用类中的getter和setter方法

  public class InvokeSetGetDemo {

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

  Class c=Class. forName( "fstest.Person");

  Object obj=c.newInstance(); //实例化对象

  setter(obj, "name", "like" , String.class );

  setter(obj, "age", 20, int .class );

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

  getter(obj, "name");

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

  getter(obj, "age");

  }

  /*@param obj 操作的对象

  *@param par 操作的属性

  *@param value 属性的值

  *@param type 参数的类型

  * */

  public static void setter(Object obj,String par,Object value,Class type)throws Exception{

  Method met=obj.getClass().getMethod("set" +initStr(par), type);

  met.invoke(obj, value);

  }

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

  Method met=obj.getClass().getMethod("get" +initStr(att)); //此方法不需要参数

  System. out .println(met.invoke(obj));

  }

  public static String initStr(String old){

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

  return str;

  }

  }

  结果:

  名字:like

  年龄:20

  4.反射来操作属性(直接来操作属性)

  public class InvokeFieldDemo {

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

  Classc=Class. forName( "fstest.Person");

  Object obj=c.newInstance();

  Field fieldName=c.getDeclaredField( "name" );//直接去的name属性

  Field fieldage=c.getDeclaredField( "age" );

  fieldName.setAccessible( true );//设置name属性可以被外部访问

  fieldName.set(obj, "like" );

  fieldage.setAccessible( true );

  fieldage.set(obj, 20);

  System. out .println("姓名:" +fieldName.get(obj)+ "年龄:"+fieldage.get(obj));

  }

  }

  结果:

  姓名:like年龄:20

  虽然可以直接操作对象,但是这样违反原则,就是所有的属性应该封装,通过getter和setter来设置和获取