通过反射和缓存区对一个类中的私有属性,私有方法进行设值,取值操作
来源:互联网 发布:惠州网络英才网 编辑:程序博客网 时间:2024/06/07 00:15
今天做项目的时候遇到一个问题,当实体类User里属性和get,set方法全是私有的,我们要怎么对其中的属性,和方法进行操作。我们知道一般的new对象是肯定行不通的。
现有两种方法来解决这个问题,其中一种方法是我们熟悉的反射操作,还有一个方法便是利用缓存区StringBuilder或者StringBuffer配合构造方法来实现。
/** * 用户表 * @author Aaron * */public class User {private Integer userId; //用户编号private String name; //真实姓名private String passWord; //密码private Integer id; //密保编号private String passWordQuestion; //密保问题答案private String idCard; //身份证private String phoneNumber; //手机号private String email; //邮箱private String birthday; //生日private String sex; //性别private String url; //用户头像private String personAddress; //个人地址private String workAddress; //工作地址private Integer Status; //账号状态private Integer roleId; //角色编号public User() { }public User(User user, StringBuilder sb, String[] flag) { for (int i = 0; i < flag.length; i++) { if("id".equals(flag[i])) { sb.append(user.userId + ";"); }else if("name".equals(flag[i])) { sb.append(user.name + ";"); }else if("password".equals(flag[i])) { sb.append(user.passWord); }else { sb.append(""); } }}public User(Integer userId, String name, String passWord) { super(); this.userId = userId; this.name = name; this.passWord = passWord; } private Integer getUserId() {return userId;}private void setUserId(Integer userId) {this.userId = userId;}private String getName() {return name;}private void setName(String name) {this.name = name;}private String getPassWord() {return passWord;}private void setPassWord(String passWord) {this.passWord = passWord;}private Integer getId() {return id;}private void setId(Integer id) {this.id = id;}private String getPassWordQuestion() {return passWordQuestion;}private void setPassWordQuestion(String passWordQuestion) {this.passWordQuestion = passWordQuestion;}private String getIdCard() {return idCard;}private void setIdCard(String idCard) {this.idCard = idCard;}private String getPhoneNumber() {return phoneNumber;}private void setPhoneNumber(String phoneNumber) {this.phoneNumber = phoneNumber;}private String getEmail() {return email;}private void setEmail(String email) {this.email = email;}private String getBirthday() {return birthday;}private void setBirthday(String birthday) {this.birthday = birthday;}private String getSex() {return sex;}private void setSex(String sex) {this.sex = sex;}private String getUrl() {return url;}private void setUrl(String url) {this.url = url;}private String getPersonAddress() {return personAddress;}private void setPersonAddress(String personAddress) {this.personAddress = personAddress;}private String getWorkAddress() {return workAddress;}private void setWorkAddress(String workAddress) {this.workAddress = workAddress;}private Integer getStatus() {return Status;}private void setStatus(Integer status) {Status = status;}private Integer getRoleId() {return roleId;}private void setRoleId(Integer roleId) {this.roleId = roleId;}}
一、利用缓存区StringBuilder或者StringBuffer来实现
1,首先因为我们的属性,方法全是私有的,所有我们在外部不能对其进行赋值操作,所以我们利用构造方法对其进行传参。
2,然后创建缓存区,用来临时存储想要取出的值,刚开始想用String字符串来保存,但是String对象中不存在存取的方法,所以不能用它来存取值,于是想到用缓存区StringBuilder或者StringBuffer来存取,其中有存数值的append方法和取数值的toString方法。
3,先在User实体类中创建含有userID,name,password的构造方法,对其属性进行赋值。
4,在main方法中创建User类,传递值。
5,创建缓存区对象StringBuilder,用来存储我们要取出的值
6,创建一个字符串数组用来标识我们传进去的值对应的属性。
7,通过new User(user, sb, flag),把User对象,缓存区,和标识通过构造函数进行传递,在构造函数里面进行操作,把值全部通过append方法保存到缓存区中。
8,最后我们只要通过toString方法得到userID,name,和password,我们看通过split方法把他们分别拿到。
2,然后创建缓存区,用来临时存储想要取出的值,刚开始想用String字符串来保存,但是String对象中不存在存取的方法,所以不能用它来存取值,于是想到用缓存区StringBuilder或者StringBuffer来存取,其中有存数值的append方法和取数值的toString方法。
3,先在User实体类中创建含有userID,name,password的构造方法,对其属性进行赋值。
4,在main方法中创建User类,传递值。
5,创建缓存区对象StringBuilder,用来存储我们要取出的值
6,创建一个字符串数组用来标识我们传进去的值对应的属性。
7,通过new User(user, sb, flag),把User对象,缓存区,和标识通过构造函数进行传递,在构造函数里面进行操作,把值全部通过append方法保存到缓存区中。
8,最后我们只要通过toString方法得到userID,name,和password,我们看通过split方法把他们分别拿到。
public class Main { public static void main(String[] args) { User user = new User(1, "zcl", "123"); StringBuilder sb = new StringBuilder(); String[] flag = {"id", "name", "password"}; new User(user, sb, flag); String[] str = sb.toString().split(";"); for (String string : str) { System.out.println(string); } }}
二、通过反射实现
反射应用在一些通用性比较高的代码中,框架大多用反射实现,在框架开发中,都是基于配置文件开发:在配置
文件中配置了类,可以通过反射得到类中所有内容,可以让类中的某个方法来执行。
1,反射的原理:
首先把.java文件保存到本地硬盘.java
编译java文件,生成.class文件
使用jvm,把class文件通过类加载到内存中
当使用反射的时候,首先需要获取到class类,得到这个类之后,就可以得到class文件里面的所有内容。
属性通过一个类File获得
构造方法通过一个类Constructor获得
普通方法通过一个类Method获得
2,使用反射操作类里面的属性
*首先获取到class类(三种方法)
Class clazz1 = User.class;
Class clazz2 = new User().getClass();
Class clazz3 = Class.forName("要获取的类的路径");
3,操作无参构造函数
a,得到Class
Class clazz = Class.forName("cn.zclong.bean.User");
b,得到User类的实例
User user = (User)clazz.newInstance();
c,设置值
user.setName("zcl");
system.out.println(user.getName());
4,操作有参构造函数
a,得到Class
Class clazz = Class.forName("cn.zclong.bean.User");
b,获取有参构造方法,传递的是有参构造方法里面的参数类型,类型使用的是Class形式传递
Constructor cs = clazz.getConstructor(Integer.class, String.class, String.class);
c,通过有参数的构造方法创建User实例并设置值
User user = (User)cs.newInstance(1, "zcl", 123);
system.out.println(user.getUserID()+":"+user.getName()+":"+user.getPassword);
5,操作属性
a,得到Class
Class clazz = Class.forName("cn.zclong.bean.User");
b,得到User类的实例
User user = (User)clazz.newInstance();
c,获得要操作的属性,参数是属性的名称
Filed f1 = clazz.getDeclaredFiled("name");
d,若操作的是私有属性,不然操作,需要设置可以操作私有属性
f1.setAccessible(true);
e,设置name的set方法,两个参数:第一个参数是类的实例,第二个参数是设置的值
f1.set(user, "zcl");//相当于 user.name = "zcl";
6,操作普通方法(解决属性和方法都为private的情况)
public static void main(String[] args) { //反射实现操作私有方法 try { //1,得到Class类 //Class c = Class.forName("cn.edu.jxau.bluedot.po.User"); //Class c = User.class; Class c = new User().getClass(); //2,得到User实例 User user = (User)c.newInstance(); //3,得到普通方法,传递两个参数,第一个参数为方法名称,第二个参数为通过方法设置的值 Method m = c.getDeclaredMethod("setName", String.class); //4,若操作的方法是私有的,需要设置值true m.setAccessible(true); //让setName方法去执行invoke()设置值,传递两个参数, //第一个参数为User实例,第二个参数为设置的值 m.invoke(user, "zcl"); //取得name的值 //1,得到getName方法 m = c.getDeclaredMethod("getName", null); //2,若操作的方法是私有的,需要设置值true m.setAccessible(true); //3,执行invoke()方法 String str = (String) m.invoke(user, null); System.out.println(str); } catch (Exception e) { e.printStackTrace(); } }
***注意:当操作的方法是静态方法时,因为静态方法调用的方式是:类名.方法名,不需要类的实例,使用反射操作静
态方法的时候,也不需要实例,在invoke()方法的第一个参数里面写null:m.invoke(null, "zcl");
以上便是解决这个问题的两种方式,最重要的还是反射知识,这个非常重要。希望这篇文章可以帮到有需要的同学。
阅读全文
2 0
- 通过反射和缓存区对一个类中的私有属性,私有方法进行设值,取值操作
- 通过反射操作类的私有属性
- 通过反射访问私有属性并对其进行修改
- 利用反射对私有属性/方法进行设置/调用
- Java基础笔记 – 通过反射机制修改类中的私有属性的值
- 通过反射访问任意类的私有方法和属性
- 通过反射修改类的私有字段值,调用私有方法
- 通过反射修改类的私有字段值,调用私有方法
- Java通过反射调用其他类的私有属性和私有方法
- 通过JAVA的反射调用类中的公有私有方法
- 使用反射操作类的私有属性(Field)和私有方法(Method)
- 通过setxxx()和getxxx()方法对类中的私有成员变量进行赋值和访问
- 通过反射返回实例的私有属性值
- 反射访问类的私有属性对象的私有方法
- java中不利用get方法获得私有属性、不利用set方法修改私有属性、通过执行私有方法getName获得私有属性、通过执行私有方法setName更改私有属性name的值
- 利用反射对私有属性/方法进行设置/调用(转自己贴)
- 通过反射执行私有方法
- 通过反射测试私有方法
- MaterialDesign学习篇(一),MaterialDesign的介绍
- 我已看破【词汇的奥秘】
- 操作封装的SQL链接——MyBatis
- Gerrit Replication Reject HostKey 解决方法
- java---继承
- 通过反射和缓存区对一个类中的私有属性,私有方法进行设值,取值操作
- LAMP搭建之Apache(源码安装)
- Java并发多线程面试题 Top 50
- Python里str函数和repr函数的区别
- 学习英语的网站
- MaterialDesign学习篇(二),Toolbar、DrawerLayout的使用
- IP判断 oj139
- ZeroClipboard实现复制功能,做到浏览器兼容
- 2017/7/24 离线赛