反射

一、获取构造函数

//通过bean的class可以获取一个类,但是如果通过Class获取对象

Class class=Class.forName("con.xiong.Student")

//class去获取student

//反射的基本使用:

//如何通过反射获取一个类,总共是有五种方法的
//但是掌握常用的三个方法

Class.forName()

Student.getClass()

Student.class()
//获取公共的构造函数

getConstructors()

//获取所有的构造函数

getDeclaredConstructors()

//获取单个构造函数

//单个公共的clazz.getConstructor()

//单个私有的getDeclaredConstructor();
//获取所有方法

getDeclaredMethods(
//获取字段名称
Field[] field = studentClass.getDeclaredFields();

二、获取类

//获取Class的三种方式
 //第一种  通过getClass
 Student student=new Student();
 Class studentClass2 = student.getClass();
 //第二种获取类信息的方式,直接通过.class
 Class<Student> studentClass1 = Student.class;
 //第三种通过CLass.forName();
 //在JDBC中获取驱动通过Class》forName(),Spring的底层代码也是这样实现的
 Class studentClass = Class.forName("com.xiong.Student");
 //通过反射获取的类信息,不管用什么方式都是指向同一个类
 System.out.println(studentClass1==studentClass);
 System.out.println(studentClass1==studentClass2);
 //判断是否为某个类的实例
 //native方法,JVM中有五个区域 堆区 栈区(本地方法栈,二是操作数栈), 元空间() 程序计数器
 //什么是本地方法栈呢? 本地方法栈是由C语言编译的
 //比如我们的Thread.sleep();
 //什么是Native 方法 简单来说一个Native Method 就是一个java调用非java代码的一个接口。
 //一个Native Method方法就是一个java的方法:该方法的实现由非java语言实现比如c这个特征并非java所持有
 //其他很多编译语言都有这一个机制如c++你可以用extern"C"告诉C++编译器调用一个c函数
 System.out.println("是否为Student的实例:"+studentClass.isInstance(Student.class));
 //instanceof需要满足继承关系他不能直接使用
 //Student 是继承自Object
// if(studentClass instanceof Object){}

 //通过类(Class)获取对象

 //获取类的第一种方式
 try {
     //1.通过newInstance(创建一个新的实例)
     Student s1 = (Student) studentClass.newInstance();
     s1.setName("ange");
     s1.setId(1);
     System.out.println(s1.show());
 } catch (InstantiationException e) {
     e.printStackTrace();
 } catch (IllegalAccessException e) {
     e.printStackTrace();
 }
//第二种方式
//通过Class对象获取指定的Constructor构造器对象
try {
    //获取对象的构造函数,有几个构造函数就可以用不同的参数表示
    Constructor constructor1 = studentClass.getConstructor();
    //对应上面的构造函数
    Student student1 =(Student) constructor1.newInstance();
    student1.setId(1);
    student1.setName("ange");
    System.out.println(student1.show()+"------->");
} catch (NoSuchMethodException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}

三、获取字段

public static void main(String[] args) {
    //1.获取Class对象
    try {
        Class clazz = Class.forName("com.xiong.Student");
        System.out.println("------------获取所有的公共字段------------");
        Field[] fields = clazz.getFields();
        for (Field field : Arrays.asList(fields)) {
            System.out.println(field.getName());
        }
        System.out.println("------------获取所有的字段------------");
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName());
        }

        System.out.println("------------获取指定的字段------------");
        //只能获取公共的
        Field age = clazz.getField("age");
        System.out.println(age.getName());
        //获取任何public/private的字段
        Field name=clazz.getDeclaredField("name");
        System.out.println(name.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    }
}

四、获取方法

public static void main(String[] args) {
    try {
        Class clazz = Class.forName("com.xiong.Student");
        System.out.println("-------获取所有公共方法(包含了父类的方法也包含Object类)------------");
        Method[] methods = clazz.getMethods();
        //常见面试题 :说几个Object中常用的方法 equals() ,hashCode(), toString(),notify(),notifyAll(),wait(),getClass,Clone()
        //equals()和==区别
        //== 1.比较的操作符中的两端操作数是不是同一个对象 2.比较两端的类型是否一致可以是父子类如果不是编译出错,3.比较的是地址,如果是比较具体的阿拉伯数字值相等返回true
        //equals  是比较两个变量的内容是不是相等 因为他们都是继承Object类 如果没有覆盖该方法则还是调用Object里面的方法 而他的值却是==的返回值
        //为什么重写equals一定要重写hashCode()方法
        //对于对象集合的判重,如果一个集合含有10000个对象实例,仅仅使用equals()方法的话,
        // 那么对于一个对象判重就需要比较10000次,随着集合规模的增大,时间开销是很大的。
        // 但是同时使用哈希表的话,就能快速定位到对象的大概存储位置,并且在定位到大概存储位置后,
        // 后续比较过程中,如果两个对象的hashCode不相同,也不再需要调用equals()方法,
        // 从而大大减少了equals()比较次数。
        //如果两个变量的hashCode()相同回出现什么问题hash碰撞的问题
        //什么是hash碰撞呢就是不同的数据计算出的hash值是一样的,2个值指向同一个空间就会有问题了
        List<Method> methods1 = Arrays.asList(methods);
        for (Method method : methods1) {
            System.out.println(method.getName());
        }
        System.out.println("-------获取所有的成员方法,包含私有的不包含继承的(不包含继承的)------------");
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }
        System.out.println("-------获取单个的------------");
        //所有公共的
        Method show = clazz.getMethod("show", null);
        System.out.println(show.getName());
        //所有的(包含私有的)
        Method text = clazz.getDeclaredMethod("show", null);
        System.out.println(text.getName());
        //调用方法 都是通过invoke方法
        Object invoke = text.invoke(Student.class.newInstance(), null);
        System.out.println(invoke);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    }

}

五、总结

1.如何通过反射获取一个类
1. 类.class()
2.对象.getClass()
3. Class.forName()
2.通过类获取对象
1.Student s=new Student()
2.Class.newInstance()
通过构造方法
3.clazz.getDeclaredConstructor().newInstance()
3.如何获取构造函数
Class clazz = Class.forName("com.xiong.Student");
 //获取所有的构造函数
 //Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
 //只获取公共的构造函数
 Constructor[] constructors1 = clazz.getConstructors();
 //获取单个构造函数
// Constructor constructor1 = clazz.getConstructor(Integer.class,String.class);
 Constructor constructor1 = clazz.getDeclaredConstructor(Integer.class);
 System.out.println(constructor1.getName()+"------");
4.如何获取字段
Class clazz = Class.forName("com.xiong.Student");
System.out.println("------------获取所有的公共字段------------");
Field[] fields = clazz.getFields();
for (Field field : Arrays.asList(fields)) {
    System.out.println(field.getName());
}
System.out.println("------------获取所有的字段------------");
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
    System.out.println(declaredField.getName());
}

System.out.println("------------获取指定的字段------------");
//只能获取公共的
Field age = clazz.getField("age");
System.out.println(age.getName());
//获取任何public/private的字段
Field name=clazz.getDeclaredField("name");
System.out.println(name.getName());
5.如何获取方法(如何调用方法)
Class clazz = Class.forName("com.xiong.Student");
System.out.println("-------获取所有公共方法(包含了父类的方法也包含Object类)------------");
Method[] methods = clazz.getMethods();
//常见面试题 :说几个Object中常用的方法 equals() ,hashCode(), toString(),notify(),notifyAll(),wait(),getClass,Clone()
//equals()和==区别
//== 1.比较的操作符中的两端操作数是不是同一个对象 2.比较两端的类型是否一致可以是父子类如果不是编译出错,3.比较的是地址,如果是比较具体的阿拉伯数字值相等返回true
//equals  是比较两个变量的内容是不是相等 因为他们都是继承Object类 如果没有覆盖该方法则还是调用Object里面的方法 而他的值却是==的返回值
//为什么重写equals一定要重写hashCode()方法
//对于对象集合的判重,如果一个集合含有10000个对象实例,仅仅使用equals()方法的话,
// 那么对于一个对象判重就需要比较10000次,随着集合规模的增大,时间开销是很大的。
// 但是同时使用哈希表的话,就能快速定位到对象的大概存储位置,并且在定位到大概存储位置后,
// 后续比较过程中,如果两个对象的hashCode不相同,也不再需要调用equals()方法,
// 从而大大减少了equals()比较次数。
//如果两个变量的hashCode()相同回出现什么问题hash碰撞的问题
//什么是hash碰撞呢就是不同的数据计算出的hash值是一样的,2个值指向同一个空间就会有问题了
List<Method> methods1 = Arrays.asList(methods);
for (Method method : methods1) {
    System.out.println(method.getName());
}
System.out.println("-------获取所有的成员方法,包含私有的不包含继承的(不包含继承的)------------");
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
    System.out.println(declaredMethod.getName());
}
System.out.println("-------获取单个的------------");
//所有公共的
Method show = clazz.getMethod("show", null);
System.out.println(show.getName());
//所有的(包含私有的)
Method text = clazz.getDeclaredMethod("show", null);
System.out.println(text.getName());
//调用方法 都是通过invoke方法
Object invoke = text.invoke(Student.class.newInstance(), null);
System.out.println(invoke);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小熊跃龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值