J2EE之反射实例化,反射动态方法调用,反射读写属性

news/2024/5/19 3:31:08 标签: java, eclipse, 反射

目录

1.什么是反射

2.类类

一切反射相关的代码都从获得类对象开始

3种获取类对象的方式:

3.反射实例化

根据类得到类构造的方法

4.反射动态方法调用

5.反射读写属性


本篇文章思维导图如下:

1.什么是反射

反射java语言中的一种机制,通过这种机制可以动态的实例化对象,读写属性,调用方法

首先建一个Student类,在后面的代码中也都要用到

package com.ltf.reflect;

public class Student {
    private String sid;

    private String sname;

    public Integer age;

    static {
        System.out.println("加载进jvm中!");
    }

    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 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());
    }
}
 

2.类类

一切反射相关的代码都从获得类对象开始


3种获取类对象的方式:

Class.forName()完整类名(全限定名/全路径名)(最常用)

.class类名

.getClass()对象

拓展:

.getName()获取全限定名

.getSimpleName()获取类名

.getPackage() 获取包名

package com.ltf.reflect;

/**
 * 获取类类的类对象的三种方式 1.Class.forName 2.类,class 3.类类的类对象的类实例.getClass();
 * 
 * 
 * @author zjjt
 *
 */
public class Demo1 {
    public static void main(String[] args) throws Exception {
        // Student.class
        Class stuCla1 = Class.forName("com.ltf.reflect.Student");
        // 通用查询
        Class stuCla2 = Student.class;
        // 通用增删改查
        Class stuCla3 = new Student().getClass();

    }
}

3.反射实例化

根据类得到类构造的方法

.getConstructor()获取单个公有构造方法

.getDeclaredConstructor()获取单个构造方法(包括私有、受保护、默认、公有)

.getConstrutors()获取所有的公有构造方法

.getDeclaredConstrutors()获取所有的构造方法(包括私有、受保护、默认、公有)

若是有参构造,需要在括号里写上参数类型

反射实例化对象的方法

.newInstance()

package com.ltf.reflect;

import java.lang.reflect.Constructor;

public class Demo2 {
    public static void main(String[] args) throws Exception {
        Class<Student> stuCla1 = (Class<Student>) Class.forName("com.ltf.reflect.Student");
        // DemoServlet stuCla1 = Class.forName("com.ltf.reflect.Student");
        Student stu1 = (Student) stuCla1.newInstance();
        // DemoServlet demo1 =(Student) stuCla1.newInstance();
        stu1.hello();
        // demo1.dopost(req,resp);

        // 反射调用有参构造器
        // 注意getDeclaredConstructor与getConstructor的区别

        Constructor<Student> c = stuCla1.getDeclaredConstructor(String.class);
        c.setAccessible(true);
        Student s1 = c.newInstance("s001");

        Constructor<Student> c2 = stuCla1.getDeclaredConstructor(String.class, String.class);
        c2.setAccessible(true);//通道
        Student s2 = c2.newInstance("s001", "s002");

        Constructor<Student> c3 = stuCla1.getDeclaredConstructor(Integer.class);
        c3.setAccessible(true);
        Student s3 = c3.newInstance(19);

    }
}
 

如果方法为私有的,需要打开访问权限:setAccessible(true);

4.反射动态方法调用

.getMethod()获取单个公有方法

.getDeclaredMethod()获取单个方法(包括私有private、受保护protected、默认、公有public)

.getMethods()获取所有公有方法

.getDeclaredMethods()获取所有的方法(包括私有、受保护、默认、公有)

括号第一个参数为方法名,如果方法有参数,第二个参数为传参类型

调用方法:invoke(对象名,有参传值)

package com.ltf.reflect;

import java.lang.reflect.Method;

/**
 * 反射动态方法调用
 * 
 * @author zjjt
 *
 */
public class Demo3 {
    public static void main(String[] args) throws Exception {
        Class<Student> stuCla1 = (Class<Student>) Class.forName("com.ltf.reflect.Student");
        Student s = stuCla1.newInstance();
        Method m1 = stuCla1.getDeclaredMethod("hello");
        // invoke参数1:类实例,在这里指Student类实例
        // 参数2:当前被调用的方法,传递的参数值
        // invoke的返回值就是被反射调用的方法的返回值,如果被调用的方法是void,那么返回null
        // Object invoke = m1.invoke(s);
        System.out.println(m1.invoke(s));

        Method m2 = stuCla1.getDeclaredMethod("hello", String.class);
        System.out.println(m2.invoke(s, "s002"));

        Method m3 = stuCla1.getDeclaredMethod("add", Integer.class, Integer.class);
        m3.setAccessible(true);
        System.out.println(m3.invoke(s, 10, 5));

    }
}
 

5.反射读写属性

.getField()获取单个属性(私有、公有、受保护、默认、静态)    

.getDeclaredFields()获取所有属性(私有、公有、受保护、默认、静态)

拓展:

.getName()获取属性名            
.getType()获取属性类型        
.getModifiers()获取属性访问修饰符    
.set(Object,Object)设置属性值,参数1:要设置属性所在对象;参数2:要设置的值;    
.get(Object)获取属性值,参数:要获取属性值的对象                

package com.ltf.reflect;

import java.lang.reflect.Field;

/**
 * 反射读写属性
 * 
 * @author zjjt
 *
 */
public class Demo4 {
    public static void main(String[] args) throws Exception {
        Class<Student> stuCla1 = (Class<Student>) Class.forName("com.ltf.reflect.Student");
        Student s = stuCla1.newInstance();
        Field f = stuCla1.getDeclaredField("sname");
        f.setAccessible(true);
        // 反射写属性
        f.set(s, "s002");
        System.out.println(s.getSname());
        // 反射读属性
        System.out.println(f.get(s));

//        比较oop与反射读取属性值的方式
        Student st=new Student("s002","ls");
        st.age=22;
        System.out.println(st.getSid());
        System.out.println(st.getSname());
        System.out.println(st.age);
        
//        反射读取该对象所有属性值的方式
        Field[] fields=stuCla1.getDeclaredFields();
        for (Field ff : fields) {
            ff.setAccessible(true);
            System.out.println(ff.getName()+":"+ff.get(st));
        }
    }
}
 

当数据繁多时oop读取过程繁多,反射读取能快速拿到所有属性值并且显示属性类型

 控制台输出为:

s002
ls
22
sid:s002
sname:ls
age:22


http://www.niftyadmin.cn/n/1713819.html

相关文章

linux与windows共享资源,samba的配置与制作

rpm -qa | grep samba 查看是否安装samba服务service smb start 启动smb服务在虚拟机中创建共享目录&#xff0c;或者用已经存在的目录&#xff1a; #mkdir /samba为了确保拷文件没问题&#xff0c;修改目录权限&#xff1a; #chmod 755 /samba修改linux虚拟机中的/et…

JSP简易增删改查

项目思维导图如下&#xff1a; Index2servlet不需要&#xff01; 使用sqlServer建表脚本如下&#xff1a; 学生表&#xff1a; 建表 create table tb_students( sid int primary key identity, sname varchar(100), steacher varchar(100), sclass int, shabbit varchar(200…

面向对象的设计法则1[Favor Composition Over Inheritance]

法则1&#xff1a;优先使用&#xff08;对象&#xff09;组合&#xff0c;而非&#xff08;类&#xff09;继承[ Favor Composition Over Inheritance ]组合1.&#xff08;对象&#xff09;组合是一种通过创建一个组合了其它对象的对象&#xff0c;从而获得新功能的复用方法。2…

面向对象的设计法则2[Program To An Interface, Not An Implementatio]

法则2&#xff1a;针对接口编程&#xff0c;而非&#xff08;接口的&#xff09;实现[ Program To An Interface, Not An Implementatio]接口1.接口是一个对象在对其它的对象进行调用时所知道的方法集合。2.一个对象可以有多个接口&#xff08;实际上&#xff0c;接口是对象所有…

J2EE之JSP标签

目录 JSP自定义标签的目的 弥补c标签没有的功能 1.标签语言的特点 2.自定义标签的开发及使用步骤 3.标签生命周期 4.z:if 标签 将属性值test定义为boolean类型&#xff0c;test为true则输出文本&#xff0c;为false不输出 5.z:set与z:out 标签 6.z:foEeach标签 JSP自定…

面向对象的设计法则3[Software Entities Should Be Open For Extension, Yet Closed For Modification ]

法则3&#xff1a;开放&#xff0d;封闭法则&#xff08;OCP&#xff09;软件组成实体应该是可扩展的&#xff0c;但是不可修改的。[ Software Entities Should Be Open For Extension, Yet Closed For Modification ] 开放&#xff0d;封闭法则1.开放-封闭法则认为我们应该试图…

J2EE之通用分页

目录 通用后台分页 1.简单的查询功能 2.通用的查询功能 通用前台分页 通用后台分页 1.简单的查询功能 编码&#xff1a;Connection建立连接 preparestatement获得预编译对象 执行查询 ResultSet结果集处理 不足之处&#xff1a; 完全重复的代码&#xff1a;Connection建…

面向对象的设计法则4

法则4&#xff1a;Liskov替换法则&#xff08;LSP&#xff09;使用指向基类&#xff08;超类&#xff09;的引用的函数&#xff0c;必须能够在不知道具体派生类&#xff08;子类&#xff09;对象类型的情况下使用它们。[ Function Thar Use Referennces To Base(Super) Classes…