个人java学习路线-反射

什么是反射,有什么用?

应该都知道光的反射吧,这个也类似,我们可以通过反射包reflect和Class类达到似是而非的效果,我们不仅可以通过反射读取其他的java类,还可以动态的编译调用类。
我们学习反射目前需要会使用Class和reflect包完整的取得一个类的结构(只是结构,类和方法),以及动态的编译运行类。

一.先了解一些可能用到的方法

1.创建properties文件,获取文件路径和通过key获取value

在这里插入图片描述
ps:properties中也是键值对储存数据的

public class AboutPath {
    public static void main(String[] args) {
        String path=Thread.currentThread().getContextClassLoader().getResource("javasetest/reflect/aboutpath/classinfo.properties").getPath();//从idea的src开始写路径
        System.out.println(path);
        Properties pro=new Properties();
        InputStream reader=null;
        try {
            reader=Thread.currentThread().getContextClassLoader().getResourceAsStream("javasetest/reflect/aboutpath/classinfo.properties");//获取文件资源保存在reader中
            pro.load(reader);	//加载到Properties类中
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        String className= pro.getProperty("User");//通过User获得value值
        System.out.println(className);//输出admin
    }
}

2.传入不定数参数

java中方法并非固定只能传入固定数量的参数,看看下面的例子:

public class ArgsTest {
    public static void main(String[] args) {
        m("asdasd","sadasd","sadsa");	//随意传入几个数组
    }
    public static void m(String... s){	//int...  三个点就是数组的意思
        for (String s1:s) {
            System.out.println(s1);		//遍历输出就行
        }
    }
}

//输出:asdasd
//		sadasd
//		sadsa

二.学习反射的一些方法

2.1实例化类

public class User {
    public User() {
        System.out.println("无参构造方法");
    }
}


public class Test2 {
    public static void main(String[] args) {
        try {
            Class c=Class.forName("javasetest.reflect.reflectfirst.User");//类加载
            Object obj=c.newInstance();			//实例化User类
            System.out.println(obj);
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
    }
}

输出无参构造方法

2.2结合propertie文件实例化类

结合propertie文件
在这里插入图片描述

public class Test3 {
    public static void main(String[] args) {
        FileReader reader=null;
        Properties pro=new Properties();
        try {
            reader=new FileReader("C:\\Users\\Lenovo\\Desktop\\java\\1javaio控制的txt\\ioAndProperties.txt");	//读取txt文件
            pro.load(reader);//加载为properties
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        String className=pro.getProperty("Class");//获得类名
        System.out.println(className);	//输出
        Class c=null;
        Object obj=null;
        try {
            c=Class.forName(className);	//类加载
            obj=c.newInstance();		//实例化类名,自动运行无参构造
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
        System.out.println(obj);
    }
}

输出结果:
在这里插入图片描述

2.3类加载自动运行静态代码块

类加载自动运行静态代码块:

public class Test4 {
    public static void main(String[] args) {
        try {
            Class.forName("javasetest.reflect.reflectfirst.MyClass");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
class MyClass{
    static {
        System.out.println("MyClass静态代码块");
    }
}

输出MyClass静态代码块

2.4反射获得类属性(值目前获得不了的)

需要被获得属性的类:

public class Student {
    public int no;
    private String name;
    protected int age;
    boolean sex;
    public static final double MATH_PI=3.1415926;
}

public class Test5 {
    public static void main(String[] args) throws Exception{
        Class studentClass=Class.forName("javasetest.reflect.reflectfirst.Student");
        Field[] fields=studentClass.getFields();//返回包含一个数组 包含所有可访问的public字段类对象。 
        System.out.println(fields.length);//查看数组
        System.out.println(fields[0].getName());
        System.out.println("--------------------------");//分割
        Field[] fields1=studentClass.getDeclaredFields();//返回一个 Field数组,包括类定义属性的各个参数。
        for (Field f:fields1) {//遍历输出
            System.out.println(Modifier.toString(f.getModifiers())+" "+f.getType().getSimpleName()+" "+f.getName());//getModifiers()返回此类或接口的Java语言修饰符,以整数编码,所以使用Modifier.toString返回描述指定修饰符中的访问修饰符标志的字符串。 
            //getType()返回一个标识了字段的声明类型 Field对象。 getSimpleName()是简称,不然像String会返回java.lang.String
            //getName()返回属性名称
        }
    }
}

输出:
在这里插入图片描述

2.5反射获得类方法(类的结构)

还是上面的Student类
public class Test6 {
    public static void main(String[] args) throws Exception {
        StringBuilder s=new StringBuilder();
        Class studentClass=Class.forName("javasetest.reflect.reflectfirst.Student");
        s.append(Modifier.toString(studentClass.getModifiers())+" class "+studentClass.getSimpleName()+" {");//操作类的方法,和上面类似
        s.append("\n");
        Field[] fields=studentClass.getDeclaredFields();
        for (Field f:fields) {//打印属性
            s.append("\t");
            s.append(Modifier.toString(f.getModifiers()));
            s.append(" ");
            s.append(f.getType().getSimpleName());
            s.append(" ");
            s.append(f.getName());
            s.append(";\n");
        }
        s.append("}");
        System.out.println(s);
    }
}

输出结果:
在这里插入图片描述
注意:是没有值的。

2.6通过反射给类属性赋值

还是上面的Student类

public class Test7 {
    public static void main(String[] args) throws Exception{
        Class studentClass=Class.forName("javasetest.reflect.reflectfirst.Student");//加载类
        Object obj=studentClass.newInstance();//实例化类并返回Object类
        Field noField=studentClass.getField("no");//返回属性值指定为no的Field对象 
        noField.set(obj,222);//设置参数到指定对象上
        System.out.println(noField.get(obj));//获得obj类的noFiled即no的值
        Field nameField=studentClass.getDeclaredField("name");//同上获得name对象
        nameField.setAccessible(true);//注意name是private的,现在私有没了,没有这个会报错-->true的值表示反射对象应该在使用时抑制Java语言访问检查,反射的强大
        nameField.set(obj,"tom");
        System.out.println(nameField.get(obj));
    }
}

输出结果:
222
tom

2.7 反射获得方法参数

被获得参数的类:

public class UseService {
    public boolean login(String name,String password){
        if ("admin".equals(name)&&"123".equals(password)){
            return true;
        }
        return false;
    }
    public void logout(){
        System.out.println("system out");
    }
}

反射:

public class Test8 {
    public static void main(String[] args) throws Exception{
        Class userServiceClass =Class.forName("javasetest.reflect.reflectfirst.UseService");
        Method[] methods= userServiceClass.getDeclaredMethods();//返回一个方法对象数组
        System.out.println(methods.length);
        for (Method m:methods) {
            System.out.print(Modifier.toString(m.getModifiers())+" "+m.getReturnType().getSimpleName()+" "+m.getName());//还是和上面一样
            System.out.print("(");
            Class[] paramterTypes=m.getParameterTypes(); //获得参数数组,注意还是没有值
            for (Class c:paramterTypes) {
                System.out.print(c.getSimpleName()+" "+",");
            }  
            System.out.print(")\n");
        }
    }
}

输出:
在这里插入图片描述
修改版:

public class Test9 {
    public static void main(String[] args) throws Exception{
        StringBuilder s=new StringBuilder();
        Class userServiceClass=Class.forName("javasetest.reflect.reflectfirst.UseService");
        s.append(Modifier.toString(userServiceClass.getModifiers())+" class "+userServiceClass.getSimpleName()+" {\n");
        Method[] userServiceMethod=userServiceClass.getDeclaredMethods();
        for (Method usm:userServiceMethod){
            s.append("\t"+Modifier.toString(usm.getModifiers())+" "+usm.getReturnType().getSimpleName()+" "+usm.getName());
            s.append("(");
            Class[] paramterTypes=usm.getParameterTypes();
            for (int i = 0; i < paramterTypes.length ; i++) {
                s.append(paramterTypes[i].getSimpleName()+" ");
                if (i!= paramterTypes.length-1){
                    s.append(",");
                }
            }
            s.append(") {");
            s.append("}\n");
        }
        s.append("}");
        System.out.println(s);
    }
}

输出:
public class UseService {
public boolean login(String ,String ) {}
public void logout() {}
}

2.8反射控制方法

被获得参数的类:

public class UseService {
    public boolean login(String name,String password){
        if ("admin".equals(name)&&"123".equals(password)){
            return true;
        }
        return false;
    }
    public void logout(){
        System.out.println("system out");
    }
}

反射:

public class Test10 {
    public static void main(String[] args) throws Exception{
        Class userServiceClass=Class.forName("javasetest.reflect.reflectfirst.UseService");
        Object obj=userServiceClass.newInstance();
        Method loginMethod=userServiceClass.getDeclaredMethod("login", String.class, String.class);//返回一个指定参数类型的方法对象 
        Object retValue=loginMethod.invoke(obj,"admin","123");//方法传参,返回用Object接受
        System.out.println(retValue);//打印返回的值
    }
}

输出:true

2.9反射获得类构造方法

被获得构造的类,含有多个构造方法

public class Vip {
    int no;
    String name;
    String birth;
    boolean sex;
    public Vip() {
    }

    @Override
    public String toString() {//自动生成的打印
        return "Vip{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", birth='" + birth + '\'' +
                ", sex=" + sex +
                '}';
    }
    public Vip(int no, String name, String birth, boolean sex) {
        this.no = no;
        this.name = name;
        this.birth = birth;
        this.sex = sex;
    }
    public Vip(int no, String name, String birth) {
        this.no = no;
        this.name = name;
        this.birth = birth;
    }
    public Vip(int no, String name) {
        this.no = no;
        this.name = name;
    }
    public Vip(int no) {
        this.no = no;
    }
}

反射:

public class Test11 {
    public static void main(String[] args) throws  Exception{
        StringBuilder s=new StringBuilder();
        Class  vipClass =Class.forName("javasetest.reflect.reflectfirst.Vip");
        s.append(Modifier.toString(vipClass.getModifiers()));
        s.append(" class ");
        s.append(vipClass.getSimpleName());
        s.append("{\n");
        Constructor[] constructors=vipClass.getConstructors();//返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造类对象。 
        for (Constructor constructor:constructors){
            s.append("\t");
            s.append(Modifier.toString(constructor.getModifiers()));
            s.append(" ");
            s.append(vipClass.getSimpleName());
            s.append("(");
            Class[] parameterTypes=constructor.getParameterTypes();
            for (Class parameterType:parameterTypes) {
                    s.append(parameterType.getSimpleName()+",");
            }
            if(parameterTypes.length>0){
                s.deleteCharAt(s.length()-1);
            }
            s.append("){}\n");
        }
        s.append("}");
        System.out.println(s);
    }
}

输出:
public class Vip{
public Vip(int){}
public Vip(int,String){}
public Vip(int,String,String){}
public Vip(int,String,String,boolean){}
public Vip(){}
}

2.10反射有参构造:

public class Test12 {
    public static void main(String[] args) throws Exception{
        Class  c =Class.forName("javasetest.reflect.reflectfirst.Vip");//上面的类
        Object obj=c.newInstance();
        Constructor con=c.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);
        System.out.println(con.newInstance(110,"tom","1999-09-09",true));
    }
}

输出:
Vip{no=110, name=‘tom’, birth=‘1999-09-09’, sex=true}

2.11反射获得类的父类和接口

public class Test13 {
    public static void main(String[] args) throws  Exception{
        Class c=String.class;
        System.out.println(c.getSuperclass().getName());
        Class[] interfaces=c.getInterfaces();
        for (Class in:interfaces) {
            System.out.println(in.getName());
        }
    }
}

输出:一个父类,三个接口
java.lang.Object
java.io.Serializable
java.lang.Comparable
java.lang.CharSequence

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值