java---------回顾 反射

1.1 类对象

  java中有一个类,java.lang.Class类,这个类的对象被称为类对象;

  类对象用来保存一个类的信息;类的信息 :这个类继承自哪个类,实现了哪些接口,有哪些方法,属性,构造方法等等;

1.2 获取类对象

  例:获取Student类的类对象:Class c = Student.class();

  对于基本类型来说他们也有自己的类对象,但是要获得基本类型的类对象,只能通过类型名.class来获得类对象;

  Class c = int.class;

1.2.2 getClass()方法

  Object类中定义了一个getClass()方法,这个方法也能获得类对象;通过类的对象获得类对象;

1.2.3 Class.forName()方法

  在Class类中有一个静态方法,forName();

public static Class forName(String className) throw ClassNotFoundException  

  1.当className 所代表的类不存在时,抛出ClassNotFoundException

  2.字符串参数必须带包名;Class c = Class.forName("java.util.ArrayList");

Class.forName() 获取类对象的方式,还有其他意义:

Class.forName() 会触发类加载的动作;有时候可以使用Class.forName() 强制进行类加载;

使用类对象,获得类对象之后的用处,如何使用;

1.3 使用类对象获取类的信息

  getName():获取类的名字,包括包名;

  getSimpleName():获取类名,不包括包名;

  getSuperClass():获得父类的类对象;

  getInterfaces():获得本类所实现的所有接口的类对象;

1.4 使用类对象获取类中方法的信息

  在Class类中,有两个方法:

  public Method[] getDeclaredMethods() throws SecurityException

  public Method[] getMethods() throws SecurityException

   Method类是在 java.lang.reflect 包中定义的类;

  Method 类用来表示方法,一个Method对象封装了一个方法的信息,可以调用Method对象的getName()方法,获得方法名,也可以直接调用Method对象的toString()方法,直接返回方法的签名;

 上述两个方法都可以返回类中的所有的方法,一个Method对象封装一个方法的信息 ,所以返回Method[]数组;

  getMethods()方法跟getDeclaredMethods()方法的区别:

  getMethods():返回 所有的公开方法,包括父类中的公开方法,但是不能返回私有方法;

  getDeclaredMethods():返回本类中定义的所有方法,包括私有方法,但是不能返回父类中的方法;

1.5 使用类对象创建类的对象

  Class类中有一个方法:newInstance(),这个方法能够通过类的无参构造方法,创建一个对象‘; 

  例: Class c = Student.class; Student stu =(Student) c.newInstance();

  这样创建对象的时候会调用对象的无参构造方法;

  

public static Object createObject(String className) throws Exception{
//通过类名获取类对象
Class c = Class.forName(className);
//通过类对象生成对象
Object b = c.newInstance();
return b;
}

2. 反射包

  2.1 Field类

  Field类封装了属性信息,一个Field类封装了一个属性的信息;

  2.1.1 获取特定属性

  Class类封装了两个方法:

  Filed getDeclaredField(String name)

  Field getField(String name)

  两个方法都能根据属性名 获取Field对象;

  区别:

  getDeclaredField():只能获得本类属性,但可以获取私有属性;

  getField():可以获得本类的公开属性,以及从父类继承到的公开属性,但是不能获取私有属性;

Class cla = Shape.class;

Field field = cla.getDeclaredField("age");
System.out.println(field.toString());

2.1.2 修改读取属性

  有了Field对象之后,使用反射来获取修改属性的值;

  修改属性值的三个要素:

  1. 确定对象; 2. 确定对象的属性 3. 确定修改对象属性的值

Class c = Shape.class;
Field field = c.getDeclaredField("age");
Shape shape2 = (Shape) c.newInstance();//Shape shape2 = new Shape();
field.setAccessible(true);
field.set(shape2, "22");
System.out.println(shape2.age);

 获取属性:

Class c = shape1.getClass();
Class c1 = Shape.class;
Class c2 = Class.forName("com.learn.test.Shape");
Field field = c.getDeclaredField("age");
String ageVal = (String) field.get(shape1);

2.2 Method类

2.2.1 获取特定的方法对象:

public Method getMethod(String name,Class[] parameterTypes);//获取公开方法包括父类的

public Method getDeclaredMethod(String name,Class[] parameterTypes);//只能获得本类的方法,但是不限于公开方法;

例子:

Method method = c.getDeclaredMethod("draw", new Class[]{FanXingLearnTwo.class});//第一个参数:方法名称。第二个参数:方法参数类型;
System.out.println(method.getName());

2.2.2 利用反射调用对象的方法:

 需要说明哪个对象调用方法;需要说明调用的是哪个方法;需要传入实参;方法可以有返回值;

对Method对象调用invoke方法;

Public Object invoke(Obeject obj,Object[] args);// obj:表示哪个对象调用方法;args:调用方法时的参数表;返回值对应Method对象所代表的方法的返回值;

Class c = Shape.class;//生成类对象
Shape shape5 = (Shape) c.newInstance();//生成类的对象
Method method = c.getDeclaredMethod("draw", new Class[]{String.class,String.class});//生成方法对象
method.setAccessible(true);//设置私有方法可以被调用
Object result = method.invoke(shape5, new Object[]{"10","xiaoxiao"});

2.3 Constructor类

通过Class类中的getConstructors()/getDeclaredConstructors()获得construct数组;

可以通过Class类中的getConstrctor()/getDeclaredConstructor()获得制定的构造方法;

可以调用Constructor中的newInstance()方法创建对象;

 如果创建对象只需要无参构造器的话,可以直接调用Class类中的new Instance方法,如果在创建对象的时候需要指定调用其他构造方法发话,就需要使用Constructor类;

例:

Class c = Shape.class;//获取类对象
Constructor cons = c.getConstructor(new Class[]{String.class,String.class});//获取指定的构造器
Shape kk = (Shape) cons.newInstance(new Object[]{"xiaoxiao","12"});//使用指定的构造器生成类的对象
System.out.println(kk.age);

 3. 反射的作用

最大程度上实现代码的通用性;

缺点:

1.效率 2.复杂度3.不易调试;

总结:

一、获取类对象的三种方式:

1.Shape shape1 = new Shape();   

Class c = shape1.getClass();
Class c1 = Shape.class;
Class c2 = Class.forName("com.learn.test.Shape");

二、类对象的方法:

1.获取类的信息:

getName():获取类的名字,包括包名;

  getSimpleName():获取类名,不包括包名;

  getSuperClass():获得父类的类对象;

  getInterfaces():获得本类所实现的所有接口的类对象;

2.获取类中方法:

public Method[] getDeclaredMethods() throws SecurityException

  public Method[] getMethods() throws SecurityException

3.获取类中属性:

Filed getDeclaredField(String name)

  Field getField(String name)

4.获取类的对象:

Shape sh = (Shape) c.newInstance();

  

原文地址:https://www.cnblogs.com/xiaoxiao1120/p/7991611.html