java高级技术:反射

反射

认识反射,获取类

获取类中的成分,并对其进行操作

作用、应用场景。

认识反射,获取类

反射:加载类,并允许以编程的方式解剖类中的各种成分(成员变量,方法,构造器等)。

反射学什么?

学习获取类的信息,操作它们

1、反射第一步:加载类,获取类的字节码:Class对象。

2、获取类中的构造器:Constructor

3、获取类的成员变量:Field对象

4、获取类的成员方法:Method对象

获取Class对象的三种方式

Class c1=类名.class

调用Class提供方法:public static Class forName(String package)

Object提供的方法:public Class getClass(); Class c3=对象.getClass();

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

        //1获得类本身 类.class
        Class c1=Student.class;
        System.out.println(c1);
        //2获得类本身 Class.forName("全类名")
        Class c2=Class.forName("Student");
        System.out.println(c2);
        //3获得类本身 对象.getClass()
        Student s=new Student();
        Class c3=s.getClass();
        System.out.println(c3);

    }
}

Class提供了从类中获取构造器的方法。

方法说明

Constructor<?>[ ]

getConstructors()

获取全部构造器(只能获取public修饰的)

Constructor<?>[]

getDeclaredConstructors()

获取全部构造器(只要存在就能拿到)

Constructor<T>getConstructor

(Class<?...parameterTypes>)

获取某个构造器(只能获得public修饰的)

Constructor<T>getDeclaredConstructor

(Class<?...parameterTypes>)

获取某个构造器(只要存在就能拿到)

Class提供了从类中获取成员方法的api

方法说明
 Method[ ]getMethods()获取类的全部成员方法(只能获得public修饰的)
 Method[ ]getDeclareMethods()获取类的全部成员方法(只要存在就能拿到)

Method getMethod(String name,Class<?...parameterTypes>)

触发某个对象的该方法执行。
Method getDeclareMethod(String name,Class<?...parameterTypes>)获取类的某个成员方法(只要存在就能拿到)

以上面两个为例获取所有类中的成分

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectDemo3 {
    public static void main(String[] args) throws Exception {
        Class c1=Student.class;
        System.out.println(c1.getName());
        System.out.println(c1.getSimpleName());

    }
    @Test
    //2获取类的构造器对象
    public void getConstructor() throws Exception{
        Class c1=Dog.class;
        Constructor[] cs=c1.getDeclaredConstructors();

        for(Constructor c:cs){
            System.out.println(c.getName()+" ");

        }
        //获取单个构造器
        Constructor c2=c1.getDeclaredConstructor(String.class,int.class);
        System.out.println(c2);
        //获取构造器的作用依然是创建对象:创建对象,
        //暴力反射
        c2.setAccessible(true);
        Dog o=(Dog)c2.newInstance("小花",12);
        System.out.println(o);
    }
    @Test
    //获取类的成员变量对象并对其进行操作
    public void getField() throws Exception{
        Class c1=Student.class;
        //获取所有成员变量对象
        Field[] fields=c1.getDeclaredFields();
        for(Field f:fields){
            System.out.println(f.getName());
        }
        //获取单个成员变量对象
        Field f1=c1.getDeclaredField("name");
        System.out.println(f1);
        Dog d=new Dog("小花",13);
        f1.setAccessible(true);
        f1.set(d,"小花花");
        String name= (String) f1.get(d);

    }
    @Test
    public void getMethod() throws Exception{
        //获取类的成员方法对象并对其进行操作
        Class c1=Student.class;
        Method[] methods=c1.getDeclaredMethods();
        for(Method m:methods){
            System.out.println(m.getName());
        }
        Method m1=c1.getDeclaredMethod("study",String.class);
        调用成员方法对象
        Student s=new Student("小明",12);
        m1.invoke(s,"java"); 
    }
}

反射的基本作用有哪些?

反射的作用?

基本作用:可以得到一个类的全部成分然后操作。

可以破坏封装性。

可以绕过泛型的约束。

最重要的用途是:适合做java的框架,基本上,主流的框架都会基于反射设计出一些通用的功能。        

import java.lang.reflect.Method;
import java.util.ArrayList;

public class ReflectDemo4 {
    public static void main(String[] args) throws Exception{
        ArrayList<String> list=new ArrayList<>();
        list.add("hello");
        list.add("world");
        list.add("java");
        Class c1=list.getClass();
        Method m1=c1.getDeclaredMethod("add",Object.class);
        m1.invoke(list,5);
        
    }
}

写一个反射框架

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;

public class SaveObjectFrameWork {
    public static void saveObject(Object obj)throws Exception
    {
        PrintStream ps=new PrintStream(new FileOutputStream("ReflectDemo1/src/obj.txt",true));
        Class c=obj.getClass();
        ps.println("--------------"+c.getSimpleName()+"-----------------");
        Field[] fields=c.getDeclaredFields();
        for(Field f:fields)
        {
            f.setAccessible(true);
            String name=f.getName();
            String value=f.get(obj)+" ";
            ps.println(name+":"+value);
        }
        ps.close();
    }
}
public class ReflectDemo6 {

    public static void main(String[] args) throws Exception{
        Student s=new Student("小马",18,"爱问问题");
        SaveObjectFrameWork.saveObject(s);

        Dog d=new Dog("小花",3);
        SaveObjectFrameWork.saveObject(d);
        Teacher t=new Teacher("小明",20,"java",5000,"211","女生","123213213123");
        SaveObjectFrameWork.saveObject(t);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值