反射:
一种动态(对象运行时)机制。
在java中对应一组API。
反射的作用:
在对象运行时获得对象的属性,方法等对象,并可以动态的操作这些对象。
在这样的API中的它将类中所有成员,都看成是对象。从对象的角度操作这些成员。通常情况下反射会应用在一些框架(framwoek)编程中。
例如:android 中的activity对象我们没有创建过,运行时,它是由android框架创建的。
学习反射的起点:
- 学习反射的起点为类对象,而不是类的对象。
类的对象:
- 自己通过new去创建的对象,类的实例。
class Point{}
/**
*类的对象,类的实例
**/
Point p1=new Point();
类对象:
- 对于类对象而言,它的类对象只有一个。
/**
*类对象,字节码对象
**/
class Point{}
Class c1=Point.class; //类对象的创建方式1
Class c2=p1.getClass(); //类对象的创建方式2
Class c3=Clss.forName("包名.类名");//类对象的创建方式3
反射中部分API的应用:
- 通过类对象而构建类的对象。
package day18;
class Person{
private String name;
private int age;
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
class Student extends Person{
}
class Employee extends Person{
}
class Teacher extends Person{
}
//class MainActivity extends Activity{}
//框架构造对象
class Framwork{
/**借助反射构建类的对象*/
public static Object newObj(String className)throws Exception{
return Class.forName(className)//构建类对象
.newInstance();//通过类对象构建类的对象
//此类中必须存在一个无参的构造函数
}
}
public class ReflectDemo1 {
public static void main(String[] args)throws Exception {
//编译时就已经确定了此对象的构建方式
Student s1=new Student();
s1.setName("s1");
s1.setAge(20);
System.out.println("s1="+s1);
Person p=(Person)Framwork.newObj("day18.Student");
p.setName("s2");
p.setAge(30);
System.out.println("s2="+p);
}
}
- 通过构造方法对象构建类的对象
class Point{
int x;
int y;
public Point(int x,int y){
this.x=x;
this.y=y;
}
//通过反射获得此方法
public double distance(int x,int y){
//return Math.sqrt(a);
return 100;
}
@Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}
public class ReflectDemo2 {
public static void main(String[] args)throws Exception {
Class<?> c=Class.forName("day18.Point");
//获得指定的构造方法对象
Constructor<?> c0=
c.getDeclaredConstructor(int.class,int.class);
//通过构造方法对象构建类的对象
Object obj=c0.newInstance(10,20);
System.out.println(obj);
//获得类中的构造函数
Constructor<?> cs0[]=
c.getDeclaredConstructors();//all
Constructor<?> cs1[]=
c.getConstructors();//public Constructor
}
}
- 通过类对象获得方法对象
package day18;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class ReflectDemo3 {
public static void main(String[] args) throws Exception{
List<String> list=
new ArrayList<>();//底层实现Object[]
list.add("A");
//list.add(100);
//通过反射获得list集合
//的add方法(参数类型为Object)
//1.获得类对象(三种方式)
Class<?> c1=list.getClass();//方式1
Class<?> c2=ArrayList.class;//方式2
Class<?> c3=Class.forName("java.util.ArrayList");//方式3
//2.通过类对象获得list集合的add方法对象
Method m=
c1.getDeclaredMethod("add",Object.class);
//3.执行对象的add方法
//执行list集合的add方法,向此集合添加一个元素100
Object result=m.invoke(list,100);
System.out.println("list="+list);//A,100
System.out.println("result="+result);//true
//获得类中的方法对象
//c1.getDeclaredMethods();all,但是不包括父类方法
//c1.getMethods()//public
}
}
- 通过类对象获得属性
package day18;
import java.lang.reflect.Field;
class View{
private int textColor;
private int background;//背景色
@Override
public String toString() {
// TODO Auto-generated method stub
return "background="+background;
}
}
public class ReflectDemo4 {
public static void main(String[] args)
throws Exception{
Class<?> c=View.class;
Field fs[]=c.getDeclaredFields();
//c.getFields()
for(Field f:fs){
System.out.println(f.getName());
}
Field f=c.getDeclaredField("background");
//给某个对象的f属性赋值
View v=new View();
//设置可访问(应用于一些在外界不可访问的属性)
f.setAccessible(true);
//给v对象的f属性赋值为100
f.set(v, 100);
System.out.println(v);
}
}