------- android培训、java培训、期待与您交流! ----------
第一节:反射的概述
一、反射的简述:
1、什么是反射机制?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2、如何对一个类进行剖析?
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。
3、反射的好处:
反射大大的提高了程序的扩展性。
4、反射的基本操作步骤:
(1)、获得Class对象,获取某个类的字节码文件对象(如果该类不确定时,可以通过配置文件,把具体的子类存储到配置文件当中去,最后在用反射技术获取指定类)。
(2)、根据实例化对象可以获取类的属性、方法或构造函数等内容。
(3)、在根据Class对象获取的内容去调用构造函数创建对象,访问属性,调用方法。
第二节:反射的应用
一、反射涉及到的对象:
1、Class类:
(1)、Class类的实例表示正在运行的java应用程序中的类和接口。
(2)、更通俗的理解就是把java中所有的类进行抽象提取用于描述类的共性内容,这就是Class类。
2、获取Class对象的三种方式:
(1)、通过Object类中的getClass()方法。(弊端:虽然通用,但是前提必须有指定类,并对该类进行对象的创建,才可以调用getClass()方法。)
(2)、使用的任意数据类的一个静态成员class,所有的数据类型都具备的一个属性。(好处:不用new对象。但是,还需要使用具体的类。)
(3)、使用Class类中的forName(String className)方法。通过给定类名来获取对应的字节码文件对象。(好处:这种方式只要有名称即可,更为方便,扩展性更强。)
3、九个预定义的Class
(1)、包括八个基本数据类型的字节码对象和一个返回值类型void的字节码对象。
(2)、基本数据类型的包装类字节码对象与基本数据类型的字节码对象之间的关系(Integer.TYPE与int.class是相等的)。
4、Class类中常用的方法;
(1)、public static Class forName(String className);给定类名的字符串形式获取对应的字节码文件对象。
(2)、public Constructor
(3)、public Constructor[] getConstructors();所有公共构造方法。
(4)、public Constructor
(5)、public Constructor[] getDeclaredConstructors();所以的构造方法。
(6)、public Field getDeclaredField(String name);获取单个的成员变量。
(7)、public Field[] getDeclaredFields();获取所有的成员变量。
(8)、public Field getField(String name);获取单个的公共的成员变量。
(9)、public Field[] getFields();获取所有的公共的成员变量。
(10)、public Method getDeclaredMethod(String name, Class... parameterTypes);获取单个方法,第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型。
(11)、public Method[] getDeclaredMethods();获取所有的方法。
(12)、public Method getMethod(String name,Class... parameterTypes); 获取单个公共的方法,第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型
(13)、public Method[] getMethods();获取所有的公共的方法
(14)、public T newInstance();获取一个类的空参实例对象
5、Constructor类
(1)、Constructor类提供关于类的单个构造方法的信息以及对它的访问权限。
(2)、Constructor类中常用方法
(2).1 public T newInstance(Object... initargs);获取一个类的有参的实例对象。
(3)、通过指定的构造函数初始化对象
思路:
(3).1 获取字节码文件对象。
(3).2 再获取给定的构造函数。
(3).3 通过构造函数初始化对象。
(3).4 代码体现
//通过指定的构造函数初始化对象
/*
1 获取单个的构造方法(无参的和有参的)
2 获取单个的构造方法(非公共的)
3 获取全部的构造方法
4 获取全部的构造方法(非公共的)
*/
import java.lang.reflect.*;
class Demo
{
public static void main(String[] args)throws Exception
{
//1 获取单个的构造方法(无参的和有参的)
Class classForname=A.class;
Constructor constructor=classForname.getConstructor();
Constructor constructor1=classForname.getConstructor(int.class);
System.out.println(constructor.toGenericString());
System.out.println(constructor1.toGenericString());
//2 获取单个的构造方法(非公共的)
Constructor constructor2=classForname.getDeclaredConstructor(String.class);
System.out.println(constructor2.toGenericString());
//获取全部的构造方法
Constructor[] constructor3=classForname.getConstructors();
for (Constructor con:constructor3)
{
System.out.println(con.toGenericString());
}
//4 获取全部的构造方法(包含非公共的)
Constructor[] constructor4=classForname.getDeclaredConstructors();
for (Constructor con1:constructor4 )
{
System.out.println(con1.toGenericString());
}
}
}
//指定一个A类
class A
{
private int sum=2;
String s=null;
int sum1=5;
public A(){}
public A(int sum)
{
this.sum=sum;
}
A(String s)
{
this.s=s;
}
public void run()
{
System.out.println("成功了");
}
}
6、Field类
//获取一个类中的字段
/*
1 获取一个类中的指定的字段
2 获取一个类中的指定的字段(非公共)
3 获取一个类中的所有的字段
4 获取一个类中的所有的字段(非公共)
*/
import java.lang.reflect.*;
class Demo1
{
public static void main(String[] args)throws Exception
{
//1 获取一个类中的指定的字段
Class classForName=A.class;
Object obj2=classForName.newInstance();
Field field=classForName.getField("count");
Object obj1=field.get(obj2);
System.out.println(obj1);
//22 获取一个类中的指定的字段(非公共)
Field field1=classForName.getDeclaredField("s");
Object obj3=field1.get(obj2);
System.out.println(obj3);
//3要是要访问私有的话 就要用到暴力反射
Field field2 =classForName.getDeclaredField("sum");
field2.setAccessible(true);
Object obj4=field2.get(obj2);
System.out.println(obj4);
//4获取一个类中的所有的字段
Field[] field3=classForName.getFields();
for (Field fid:field3 )
{
System.out.println(fid.get(obj2));
}
//5 获取一个类中的所有的字段(要是有私有的话不进行暴力反射会出现异常)
Field[] field4 =classForName.getDeclaredFields();
for (Field fid1:field4 )
{
fid1.setAccessible(true);
System.out.println(fid1.get(obj2));
}
}
}
//自定义一个A类
class A
{
private int sum=9;
public int count=8;
String s="你好啊";
}
7、Method类
//获取一个类中的方法用反射
/*
1 获取 一个类中的无参或有参的方法
2 获取 一个类中的无参或有参的方法(非公共)
3 获取一个类中的所有的方法
4 获取一个类中的所有的方法(非公共)
*/
import java.lang.reflect.*;
class Demo2
{
public static void main(String[] args)throws Exception
{
//1 获取 一个类中的无参或有参的方法
Class classForName=A.class;
Object obj=classForName.newInstance();
Method method=classForName.getMethod("run");
Method method1=classForName.getMethod("add",int.class);
method.invoke(obj);
method1.invoke(obj,5);
//2 获取 一个类中的无参或有参的方法(非公共)
Method method2=classForName.getDeclaredMethod("show");
method2.invoke(obj);
//3 获取一个类中的所有的方法
Method[] method3=classForName.getMethods();
for (Method method4:method3)
{
System.out.println(method4.toGenericString());
}
//4 获取一个类中的所有的方法(非公共)
Method[] method5 =classForName.getDeclaredMethods();
for (Method method6:method5 )
{
System.out.println(method6.toGenericString());
}
}
}
//自定义一个A类
class A
{
private int sum=9;
public void add(int sum)
{
System.out.println(sum);
}
public void run()
{
System.out.println("成功了");
}
void show()
{
System.out.println("hahahahahaha");
}
}
8、用反射执行一个类中的main方法
//反射执行一个类中的 方法
/*
思路;
1 main方法实际也是一个方法
2 而是接收一个String类型的数组
*/
import java.lang.reflect.*;
class Demo3
{
public static void main(String[] args)throws Exception
{
Class classForName=A.class;
//第一种方式
Method method =classForName.getMethod("main",String[].class);
method.invoke(null,(Object)new String[]{"wo","lai","le"});
//第二种方式
Method method1 =classForName.getMethod("main",String[].class);
method1.invoke(null,new Object[]{new String[]{"ha","ha","le"}});
}
}
//自定义一个A类
class A
{
public static void main(String[] args)
{
for (String s:args )
{
System.out.println(s);
}
}
}
9、数组的反射
------- android培训、java培训、期待与您交流! ----------