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();