反射

反射

通过反射获取堆区中对应的字节码文件对象 Class。

1、反射介绍:

1.通过字节码文件对象,使用该对象来获取一个类的所有的信息
(成员方法 成员变量 构造方法 静态方法 常量 访问权限修饰符 泛型 …包括私有)
2.Java是面向对象语言,Java编译生成的字节码文件应该也是一个对象,而这个对象不需要我们定义,
3.Java已经事先定义好了一个类叫做Class
4.Class类是用来描述现实事物的,是Java语言的最基本单位,类作为一个概念存在,概念本身也是一个对象
而我们使用Class类来描述这个概念类

2、反射的好处: 框架的核心

1.通过反射技术可以获取到字节码文件对象,
2.使用这个字节码文件对象就可以获取到一个类的所有信息,包括私有
【构造方法对象,成员变量对象,成员方法对象,访问权限修饰符对象…】
3.使得代码的可维护和可扩展大大提高。

3、了解相关的反射的的对象和包

java.lang.reflect包
Class 类对象
Constructor 构造方法对象
Method 成员方法对象
Field 成员变量对象
Modifier 访问权限修饰符对象

反射对象:

package com.DZY.reflect;

public class Student {
 private String sid;
 private String sname;
 public Integer age;

static{
  System.out.println("加载T237-DZY!");
 }

public Student() {
  super();
  System.out.println("调用无参构造方法创建了一个学生对象");
 }

public Student(String sid) {
  super();
  this.sid = sid;
  System.out.println("调用带一个参数的构造方法创建了一个学生对象");
 }

public Student(String sid, String sname) {
  super();
  this.sid = sid;
  this.sname = sname;
  System.out.println("调用带二个参数的构造方法创建了一个学生对象");
 }

 @SuppressWarnings("unused")
 private Student(Integer age) {
  System.out.println("调用Student类私有的构造方法创建一个学生对象");
  this.age = age;
 }

public String getSid() {
  return sid;
 }

public void setSid(String sid) {
  this.sid = sid;
 }

public String getSname() {
  return sname;
 }

public void setSname(String sname) {
  this.sname = sname;
 }
 
 public Integer getAge() {
  return age;
 }
 
 public void setAge(Integer age) {
  this.age = age;
 }
public void hello() {
  System.out.println("你好!我是" + this.sname);
 }

public void hello(String name) {
  System.out.println(name + "你好!我是" + this.sname);
 }

@SuppressWarnings("unused")
 private Integer add(Integer a, Integer b) {
  return new Integer(a.intValue() + b.intValue());
 }
}

1.获得类对象的三种方式。

代码如下:

package com.DZY.reflect;

public class Demo1 {
     public static void main(String[] args) throws Exception {
     //1、Class.forName("全路径名"); jdbc/自定义mvc框架要用 
     //  Class  stu=  Class.forName("com.DZY.reflect.Student");//包名.类名。
     //直接远行:运行结果:他会调用静态代码块。

   // 2、类名.class 结合泛型做通用分页查询方法会用.
/*   Class   stu=Student.class;
     System.out.println(stu);*/
     //直接远行:获得类的全路径名。

   //3、类java.lang.Class实例(Student.class)的类实例的getClass()获取 通用的增删改结合泛型使用
/*      Student    stu=new  Student();
      Class  stu2=stu.getClass();
      System.out.println(stu2);*/
    //获得类对象的静态代码块、无参构造方法、类的全路径名。
     //如果没有打印语句stu2,就不会出现类的全路径名。 
 }
}

  • 1、Class.forName(“全路径名”); jdbc/自定义mvc框架要用
    在这里插入图片描述
  • 2、类名.class 结合泛型做通用分页查询方法会用.

在这里插入图片描述

  • 3、类java.lang.Class实例(Student.class)的类实例的 getClass()获取 通用的增删改结合泛型使用
    在这里插入图片描述

2、反射实例化对象

package com.DZY.reflect;

import java.lang.reflect.Constructor;

/**
 * 利用反射进行对象的实例化 之前:通过new关键字进行实例化
 *  现在: 通过java.lang.reflect.construct来实例化对象
 *  优势:
 *  1、能够对未知的对象进行实例化
 *  2、能够对私有构造器实例化对象
 * 
 * @author Aromanic150
 *
 */

public class Demo2 {
public static void main(String[] args) throws Exception, IllegalAccessException {
/*   Student  stu=new  Student();
   Class  stugc=stu.getClass();*/
   //获得类对象的静态代码块、无参构造方法.

   Class<Student>   stugc=Student.class;
   //newInstance这个方法默认是使用无参构造器去实例化对象
/*   Student  stu2=(Student)stugc.newInstance();
   System.out.println(stu2);*/

   //调用有参构造器去实例化对象
/*  Constructor<Student> constructor = stugc.getConstructor(String.class);
  Student stu2 = (Student) constructor.newInstance("kin");
  System.out.println(stu2.getSid());*/
     //调用方法参数,然后设置参数值

  //调用有构造器去实例化对象
/*  Constructor<Student> constructor = stugc.getConstructor(String.class,String.class);
  Student stu2 = (Student) constructor.newInstance("1","DZY");
  System.out.println(stu2.getSid());
  System.out.println(stu2.getSname());*/

//  调用私有构造器去实例化对象
//   java.lang.NoSuchMethodException: 
//  getConstructor与getDeclaredConstructor的区别(getConstructor只能获取被public修饰的构造器,getDeclaredConstructor被所有关键字修饰的构造器)
//  Class com.zking.reflect.Demo2 can not access a member of class com.zking.reflect.Student with modifiers "private"

  Constructor<Student> constructor = stugc.getDeclaredConstructor(Integer.class);
  constructor.setAccessible(true);
  Student stu2 = (Student) constructor.newInstance(18);
  System.out.println(stu2.getAge());
}
}

1、第一个打印结果:
在这里插入图片描述
2、第二个打印结果:
在这里插入图片描述
3、第二个打印结果:
在这里插入图片描述
4、第四个打印结果:

在这里插入图片描述
5、第五个打印结果:
在这里插入图片描述

3、反射动态调用方法:

代码如下:

package com.DZY.reflect;

import java.lang.reflect.Method;
/**
 * 动态方法调用
 *  构造方法是不是方法?
 * @author Aromanic150
 *
 */
 
public class Demo3 {
public static void main(String[] args) throws Exception, SecurityException {
 Student stu = new Student();
 stu.setSname("DZY");//设置名字
 Class<? extends Student> stugc = stu.getClass();
 /*Method m= stugc.getDeclaredMethod("hello");
 m.invoke(stu);*/
 //调用Student里hello方法

/* Method m= stugc.getDeclaredMethod("hello",String.class);
 m.invoke(stu,"kin");*/
 //调用Student里hello方法逗号后面加参数类型

Method m= stugc.getDeclaredMethod("add",Integer.class,Integer.class);
 m.setAccessible(true);//方法设置了私有化,需要给权限;
 //Method.invoke的返回值是被动态调用的方法的返回值
 Object invoke = m.invoke(stu,20,5);
 System.out.println(invoke);
}
}

1、第一个打印结果:
在这里插入图片描述
2、第二个打印结果:

在这里插入图片描述
3、第三个打印结果:
在这里插入图片描述

4、反射读取属性

代码如下:

package com.DZY.reflect;

import java.lang.reflect.Field;
/**
 * 反射读写属性 自定义标签库、通用分页、自定义mvc也要用
 * 
 * 5. 访问修饰符
   getModifiers()
    java:
    private 1
    protected 2
    public 4
    static 8
    final abstract....
    怎么判定属性或方法被那些修饰符所修饰呢?
    getModifiers
    3 private protected
    5 
 * 
 * @author Aromanic150
 *
 */
public class Demo4 {
public static void main(String[] args) throws Exception, IllegalAccessException {
 Student stu = new Student("1", "DZY");
 stu.age = 22;
 /*System.out.println(stu.getSid());
 System.out.println(stu.getSname());*/
 Class<? extends Student> stugc = stu.getClass();

 // Field f = stugc.getDeclaredField("age");
 // f.setAccessible(true);
 // System.out.println(f.get(stu));

 // 获取当前Student实例中的stu所有属性及其属性值
 Field[] fields = stugc.getDeclaredFields();
 for (Field field : fields) {
  field.setAccessible(true);
  System.out.println(field.getName() + ":" + field.get(stu));
 }
}
}

1、第一个打印结果:

在这里插入图片描述
2、第二个打印结果:
在这里插入图片描述
3、第三个打印结果:
在这里插入图片描述
其他详细,请点击下面网站
https://blog.csdn.net/lyk1599021827/article/details/90044770#2__386

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值