java反射的基本内容

首先说一下获取类名称的几种方式

package org.java;

/**
 * @author yangkun
 * @date 2021-04-07
 */
public class Reflect {
    public static void main(String[] args) {
        Class<? extends Object> c1 = Reflect.class;
        System.out.println(c1.getName());

        Reflect reflect = new Reflect();
        Class<? extends Reflect> c2 = reflect.getClass();
        System.out.println(c2.getName());

        try {
            Class<Reflect> c3 = (Class<Reflect>) Class.forName("org.java.Reflect");
            System.out.println(c3.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

获取成员方法

//获取该类的所有方法但是不包括父类的方法
public Method getDeclaredMethod(String name,Class<?>...paramterTypes);
//获取该类以及父类的所有public方法
public Method getMethod(String name,Class<?>...paramterTypes)

package org.java;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author yangkun
 * @date 2021-04-07
 */
public class Person {
    private String name="crossover" ;
    private String msg ;

    public Person(String name, String msg) {
        this.name = name;
        this.msg = msg;
        System.out.println(name+"的描述是"+msg);
    }
    public Person() {
        super();
    }
    public void say(String name ,String msg){
        System.out.println(name+"说:"+msg);
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
	


    public static void main(String[] args) {
        try {
            //首先获取类类型
            Class p1 =Class.forName("org.java.Person");
            //通过newInstance()方法生成一个实例
            Object o1 = p1.newInstance();
            //获取该类的say方法
            Method m1 = p1.getMethod("say", String.class, String.class);
            //通过invoke方法调用该方法
            m1.invoke(o1,"张三","你好啊");

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

结果输出:

张三说:你好啊

获取成员变量

1.public Field getDeclaredFiled(String name)//获得该类所有的成员变量,但不包括父类的。
2.public Filed getFiled(String name)//获得该类的所有的public变量,包括其父类的。

public static void main(String[] args) {

        try {
            Class c1 = Class.forName("org.java.Person");
            Field field = c1.getDeclaredField("name");
            Object o1 = c1.newInstance();
            /**
             * 由于Person类中的name变量是private修饰的,
             * 所以需要手动开启允许访问,是public修饰的就不需要设置了
             */
            field.setAccessible(true);
            Object name = field.get(o1);
            System.out.println(name);
        } catch (Exception e) {
            e.printStackTrace();
        }
}

获取构造方法

1.public Constructor getDeclaredConstructor(Class<?>...parameterTypes)//获取该类的所有构造方法,不包括父类的。
2.public Constructor getConstructor(Class<?>...parameterTypes)//获取该类的所有public修饰的构造方法,包括父类的。

在之前的Person类中有以下的构造方法:

public Person(String name, String msg) {
	this.name = name;
	this.msg = msg;
}

我们可以通过以下方法来获取Person类的构造方法:

Constructor dc1 = c1.getDeclaredConstructor(String.class,String.class) ;

具体代码如下:

Constructor dc1 = c1.getDeclaredConstructor(String.class,String.class) ;
dc1.setAccessible(true);
dc1.newInstance("小明","很帅") ;

dc1.newInstance(“小明”,“很帅”);
方法调用了Person类中的:

public Person(String name, String msg) {
    this.name = name;
    this.msg = msg;
    System.out.println(name+"的描述是"+msg);
}

这个构造方法,如果不传参数的话,那么调用的就是无参的构造方法。
输出结果为:

小明的描述是很帅

通过反射了解集合泛形的本质

package org.java;


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

/**
 * @author yangkun
 * @date 2021-04-07
 */
public class GenericIssue {
    public static void main(String[] args) {
        List list1  = new ArrayList();
        List<String> list2 = new ArrayList<String>();

        list2.add("你好");
        //	list2.add(11) ;加上泛型之后在编译期间只能添加String,不然会报错。
        System.out.println("list2的长度是:"+list2.size());

        Class c1 = list1.getClass();
        Class c2 = list2.getClass();
        System.out.print("c1,c2是否相等:");
        System.out.println(c1==c2);

        try {
            Method method = c2.getDeclaredMethod("add", Object.class);
            //在这里加入int类型,在上面如果加入int会出现编译报错。
            method.invoke(list2, 123) ;

            //list2的长度增加了,说明添加成功了
            System.out.println("现在list2的长度是:"+list2.size());
            /**
             * 所以可以看出,泛型只是在编译期间起作用,在经过编译进入运行期间是不起作用的。
             * 就算不是泛型要求的类型也是可以插入的。
             */
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值