Common-BeanUtils研究心得

2024-05-14 22:38
文章标签 心得 common 研究 beanutils

本文主要是介绍Common-BeanUtils研究心得,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


BeanUtils 介绍

       所谓 BeanUtils 为何要开发呢, 每个工程师或许在写 JavaBean 的时候, 都会乖乖地去写 getters 和 setters, 就是 getXXX() 及 setXXX() methods, 但是当你的 object 是动态产生的, 也许是用档案, 也许是其它原因, 那你该如何去存取数据呢 !!几个例子你可能会用到 BeanUtils, 当然, 这是已经存在的项目了。

  • BSF: Script Language 和 Java Object Model 之间
  • Velocity/ JSP: 使用 template 建立相似的网页
  • jakarta taglibs/ Struts/ Cocoon: 建立自己特殊的 Tag Libraries for JSP 或 XSP
  • ant build.xml/ tomcat server.xml: XML-based 的 设定档案 ( configuration resources )

       你大可以使用 java api 中的 java.lang.reflect 及 java.beans 来达到这些数据交换 ~~ 不过呢, 难度有点高 ,但是, BeanUtils 将会减低你开发的时间 !!目前最新的 stable 版本为 1.9.3,下载地址如下:

  • commons-beanutils-1.9.3.jar;
  • commons-logging.jar;

       BeanUtils 的 Java API 主要的 package 总共四项:

       1. org.apache.commons.beanutils;
       2. org.apache.commons.beanutils.converters;
       3. org.apache.commons.beanutils.locale;
       4. org.apache.commons.beanutils.locale.converters;

   后三个包主要是用于数据的转换,围绕着一个 Converter 接口,该接口只有一个方法:java.lang.Object convert(java.lang.Class type, java.lang.Object value) ,用于将一个 value 转换成另一个类型为 type 的 Object。在将字符串类型的数据转换成日期类型时会使用此方法。

测试用的Bean

       在开始所有的测试之前,我写了一个简单的 Bean,以便于测试,代码如下:

package com.study.java.domain;import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;/**
* @Name: User
* @Description: JavaBean-User信息类 
* @Author: XXX
* @CreateDate: XXX
* @Version: V1.0*/
public class User implements Serializable {private static final long serialVersionUID = 5210726534179789239L;private String name ;private int age ; private boolean gender ;   //性别:trye-男,false-女private Date birthday ; //生日private String[] hobbies ; //爱好private String address ; private List<String> strong ; //特长private Map<String, String> fault ; //缺点private Student Student ; //内嵌学生对象public User() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public boolean isGender() {return gender;}public void setGender(boolean gender) {this.gender = gender;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public String[] getHobbies() {return hobbies;}public void setHobbies(String[] hobbies) {this.hobbies = hobbies;}public List<String> getStrong() {return strong;}public void setStrong(List<String> strong) {this.strong = strong;}public Map<String, String> getFault() {return fault;}public void setFault(Map<String, String> fault) {this.fault = fault;}public Student getStudent() {return Student;}public void setStudent(Student student) {Student = student;}}

Commons-Beanutils工具详解

BeanUtils的使用

       Beanutils工具在使用时几乎只用到以下几个方法,其中一个方法通常情况下都是使用匿名内部类,用来注册日期类型转换器,以将字符串类型的数据转换成指定格式的日期类型。

  • BeanUtils.setProperty(bean, name, value):为指定bean实例的属性设值,等同于bean.setXXX()方法;其中bean是指你将要设置的对象,name指的是将要设置的属性(写成”属性名”),value(想要设置的属性值);

  • BeanUtils.copyProperties(bean, name, value):与上边的setProperty方法功能相同;

  • ConvertUtils.register(Converter converter , Class clazz):类型转换器注册方法,当需要将String数据转换成引用数据类型(自定义数据类型时,例如Date类型),需要使用此方法实现转换;

  • BeanUtils.populate(bean,Map):将Map集合中的数据注入到JavaBean的属性中去,其中Map中的key必须与目标对象中的属性名相同,否则不能实现拷贝;

  • BeanUtils.copyProperties(newObject,oldObject):实现对象之间的拷贝。

说明:自定义数据类型使用BeanUtils工具时必须具备的条件

       自定义数据类型使用BeanUtils工具时,本身必须具备getter和setter方法,因为BeanUtils工具本身也是一种内省的实现方法,所以也是借助于底层的getter和setter方法进行转换的。

/*** @Name: testSetProperty* @Description: * 1、设置Bean对象的单个属性*   public static void setProperty(Object bean, String name, Object value)*   =*   public static void copyProperty(Object bean, String name, Object value)* @Author: XXX* @Version: V1.0* @CreateDate: XXX* @Parameters: @throws Exception* @Return: void*/@Testpublic void testSetProperty() throws Exception {System.out.println(user);//设置String类型的属性BeanUtils.setProperty(user, "user", "李四") ;//设置int类型的属性BeanUtils.setProperty(user, "age", 25) ;//设置boolean类型的属性BeanUtils.setProperty(user, "gender", "false") ;//设置Date类型的属性//异常信息:DateConverter does not support default String to 'Date' conversion.//注册String->日期类型转换器ConvertUtils.register(new Converter() {@Overridepublic Object convert(Class type, Object value) {if(type != Date.class) {return null ;}if(value == null && "".equals(value.toString().trim())) {return null ;}SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;Date date = null ;try {date = sdf.parse((String) value) ;} catch (ParseException e) {throw new RuntimeException(e) ;}return date;}}, Date.class) ;BeanUtils.setProperty(user, "birthday", "2016-92-11") ;//设置数组类型的属性String[] hobbies = {"11", "22", "33"} ;BeanUtils.setProperty(user, "hobbies", hobbies) ;//设置List、Set、Map、内嵌对象等...System.out.println(user);}
/*** @Name: testPupulate* @Description: * 2、将Map<String, Object>集合中的内容设置到JavaBean的属性上* 说明:*   Map的key:必须与JavaBean的属性名称相同;*   Map的value:注入到JavaBean的属性;* 备注:*   此方法经常用于将表单提交的参数设置到表单Bean对象中* @Author: XXX* @Version: V1.0* @CreateDate: XXX* @Parameters: * @Return: void*/@Testpublic void testPupulate() throws Exception {Map<String, Object> map = new HashMap<String, Object>() ;//字符串->字符串属性map.put("name", "李大魁") ;//字符串->整型属性map.put("age", "25") ;//字符串->布尔型属性map.put("gender", "false") ;//字符串->日期类型属性map.put("birthday", "2016-12-10") ;//字符串->数组类型属性String[] hobbies = {"11", "22", "33"} ;map.put("hobbies", hobbies) ;//字符串->List集合属性List<String> strong = new ArrayList<String>() ;strong.add("1111") ;strong.add("22222") ;strong.add("33333") ;map.put("strong", strong) ;//字符串->Map集合属性Map<String, String> fault = new HashMap<String, String>() ;fault.put("学习222", "偷懒,反应慢") ;fault.put("感情222", "磨叽,不勇敢") ;map.put("fault", fault) ;//字符串->内嵌对象属性Student student = new Student("三思", "25") ;map.put("student", student) ;User user = new User() ;//注册日期类型转换器ConvertUtils.register(new Converter() {@Overridepublic Object convert(Class type, Object value) {if(type != Date.class) {return null ;}if(value == null || "".equals(value.toString().trim())) {return null ;}SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;Date date = null ;try {date = sdf.parse((String) value);} catch (ParseException e) {e.printStackTrace();}return date;}}, Date.class) ;//将Map集合注入到JavaBeanBeanUtils.populate(user, map) ;System.out.println(user);}

       下边是我在开发中常用到的表单数据转换工具类WebUtils:

package com.study.java.utils;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;/**
* @Name: WebUtils
* @Description: Web工具类
* @Author: XXX
* @CreateDate: XXX
* @Version: V1.0*/
public class WebUtils {private static final String FORMAT = "yyyy-MM-dd" ;/*** @Name: fillBean* @Description: 将Map集合中的数据封装到JavaBean* 说明:*   Map的key:与属性名称保持一致;*   Map的value:设置为属性值;* @Author: XXX* @Version: V1.0* @CreateDate: XXX* @Parameters: @param map* @Parameters: @param clazz* @Return: T*/public static <T> T fillBean(Map<String, Object> map, Class<T> clazz) {T bean = null ;try {bean = clazz.newInstance() ; //注册日期类型转换器ConvertUtils.register(new Converter() {@Overridepublic Object convert(Class type, Object value) {if(type != Date.class) {return null ;} if(value == null || "".equals(value.toString().trim())) {return null ;}SimpleDateFormat sdf = new SimpleDateFormat(FORMAT) ;Date date = null ;try {date = sdf.parse((String) value) ;} catch (ParseException e) {e.printStackTrace();}return date;}}, Date.class) ;//将Map集合中的数据封装到JavaBeanBeanUtils.populate(bean, map) ;} catch (Exception e) {throw new RuntimeException(e) ;}return bean ;}/*** @Name: copyProperties* @Description: 实现JavaBean对象之间的属性复制* 说明:原对象与目标对象内的属性名称必须相同* @Author: XXX* @Version: V1.0* @CreateDate: XXX* @Parameters: @param tClazz* @Parameters: @param oClazz* @Return: void*/public static <T, O> void copyProperties(Class<T> tClazz, Class<O> oClazz) {try {T target = tClazz.newInstance() ;O origin = oClazz.newInstance() ;//注册日期类型转换器ConvertUtils.register(new Converter() {@Overridepublic Object convert(Class type, Object value) {if(type != Date.class) {return null ;} if(value == null || "".equals(value.toString().trim())) {return null ;}SimpleDateFormat sdf = new SimpleDateFormat(FORMAT) ;Date date = null ;try {date = sdf.parse((String) value) ;} catch (ParseException e) {e.printStackTrace();}return date;}}, Date.class) ;//将源对象内的属性值复制到目标对象的属性上BeanUtils.copyProperties(target, origin) ;} catch (Exception e) {throw new RuntimeException(e) ;}}
}
PropertyUtils的使用

       这个类和 BeanUtils 类很多的方法在参数上都是相同的,但返回值不同。BeanUtils 着重于”Bean”,返回值通常是 String,而 PropertyUtils 着重于属性,它的返回值通常是 Object。

       在 PropertyUtils 中会区分为三种 method 状态:

  • Simple:如果你是用到 primitive 语法, 如 int, String 或其它自行开发的 objects 等等, 只需要单一的对象就可以取得数据;
PropertyUtils.getSimpleProperty(Object bean, String name);
  • Indexed:如果你是用到 Collection 或 List 实作出来的 objects , 只需要使用一个 index 数值就可以取得数据的型态;
PropertyUtils.getIndexedProperty(Object bean, String name);
PropertyUtils.getIndexedProperty(Object bean, String name, int index);
PropertyUtils.setIndexedProperty(Object bean, String name, Object value);
PropertyUtils.setIndexedProperty(Object bean, String name, int index, Object value);
  • Mapped:如果你是用到 Map 延伸出来的 objects , 只需要使用一个 key 值就可以取得数据;
PropertyUtils.getMappedProperty(Object bean, String name);
PropertyUtils.getMappedProperty(Object bean, String name, String key);
PropertyUtils.setMappedProperty(Object bean, String name, Object value);
PropertyUtils.setMappedProperty(Object bean, String name, String key, Object value);

但是如果你是巢状(nested)的数据结构, 你该如何取得你要的数据呢?

PropertyUtils.getNestedProperty(Object bean, String name);
PropertyUtils.setNestedProperty(Object bean, String name, Object value);

只需要简单地使用 “.”, 就可以得到你要的数据了。

ConstructorUtils的使用

       这个类中的方法主要分成两种,一种是得到构造方法,一种是创建对象。事实上多数时候得到构造方法的目的就是创建对象,这里只介绍一下创建对象。

//根据一个 java.lang.Class 以及相应的构造方法的参数,创建一个对象
static java.lang.Object ConstructorUtils.invokeConstructor(java.lang.Class klass, java.lang.Object[] args) ;

       测试使用的JavaBean:

package com.study.java.domain;import java.io.Serializable;/**
* @Name: Month
* @Description: 测试JavaBean
* @Author: XXX
* @CreateDate: XXX
* @Version: V1.0*/
public class Month implements Serializable {private static final long serialVersionUID = -3631848758000270789L;private String name ;private int value ;private int[] days = {11, 22, 33, 44, 55} ;public Month() {}public Month(String name, int value) {this.name = name;this.value = value;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getValue() {return value;}public void setValue(int value) {this.value = value;}public int[] getDays() {return days;}public void setDays(int[] days) {this.days = days;}}

       测试代码:

Object obj=ConstructorUtils.invokeConstructor(Month.class, {new Integer(1), "Jan"}); 
Month month=(Month)obj;
try { System.out.println(BeanUtils.getProperty(month,"value")); 
} catch (Exception e) {e.printStackTrace();
}

       如果输出证明,构造方法的调用是成功的。
       如果需要强制指定构造方法的参数类型,可以这样调用:

Object[] args={new Integer(1), "Jan"}; 
Class[] argsType={int.class, String.class}; 
Object obj = null ;
obj = ConstructorUtils.invokeExactConstructor(Month.class, args, argsType); //argsType 指定了参数的类型
Month month=(Month)obj; 
System.out.println(BeanUtils.getProperty(month,"value")); 

       补充:创建对象还有一个方法:invokeExactConstructor,该方法对参数要求更加严格,传递进去的参数必须严格符合构造方法的参数列表。例如:

Object[] args={new Integer(1), "Jan"}; 
Class[] argsType={int.class, String.class}; 
Object obj = null ;
//下面这句调用将不会成功,因为 args[0]的类型为 Integer,而不是 int 
//obj = ConstructorUtils.invokeExactConstructor(Month.class, args);
//这一句就可以,因为 argsType 指定了类型。 
obj = ConstructorUtils.invokeExactConstructor(Month.class, args, argsType); 
Month month=(Month)obj;
System.out.println(BeanUtils.getProperty(month,"value"));
MethodUtils的使用说明

       与 ConstructorUtils 类似,不过调用的时候,通常需要再指定一个 method name 的参数。

DynaClass/DynaBean

       这似乎是BeanUtils中最有趣的部分之一了,很简单,简单到光看这两个接口中的方法会不明白为什么要设计这两个接口?不过看到ResultSetDynaClass后,就明白了。下面是java doc中的代码:

ResultSet rs = ...; 
ResultSetDynaClass rsdc = new ResultSetDynaClass(rs); 
Iterator rows = rsdc.iterator();
while (rows.hasNext()) { DynaBean row = (DynaBean) rows.next(); ... process this row ... 
} 
rs.close();

       原来这是一个ResultSet的包装器,ResultSetDynaClass实现了DynaClass,它的iterator方法返回一个ResultSetIterator,则是实现了DynaBean接口。在获得一个DynaBean之后,我们就可以用:

DynaBean row = (DynaBean) rows.next(); 
System.out.println(row.get("field1")); //field1是其中一个字段的名字

       再看另一个类RowSetDynaClass的用法,代码如下:

String driver="com.mysql.jdbc.Driver"; 
String url="jdbc:mysql://localhost/2hu?useUnicode=true&characterEncoding=GBK";  String username="root"; 
String password="";
Connection con=null; 
PreparedStatement ps=null; 
ResultSet rs=null; 
try { Class.forName(driver).newInstance();con = DriverManager.getConnection(url); ps=con.prepareStatement("select * from forumlist");rs=ps.executeQuery(); //先打印一下,用于检验后面的结果。while(rs.next()){System.out.println(rs.getString("name"));}rs.beforeFirst();//这里必须用beforeFirst,因为RowSetDynaClass只从当前位置向前滚动  RowSetDynaClass rsdc = new RowSetDynaClass(rs); rs.close();ps.close(); List rows = rsdc.getRows();//返回一个标准的List,存放的是DynaBean for (int i = 0; i <rows.size(); i++) { DynaBean b=(DynaBean)rows.get(i); System.out.println(b.get("name")); }
} catch (Exception e) {e.printStackTrace();
} finally {try {con.close();} catch (Exception e) {e.printStackTrace();}
}

       是不是很有趣?封装了ResultSet的数据,代价是占用内存。如果一个表有10万条记录,rsdc.getRows()就会返回10万个记录。

       需要注意的是ResultSetDynaClass和RowSetDynaClass的不同之处:

       1. ResultSetDynaClass是基于Iterator的,一次只返回一条记录,而RowSetDynaClass是基于List的,一次性返回全部记录。直接影响是在数据比较多时ResultSetDynaClass会比较的快速, 而RowSetDynaClass需要将ResultSet中的全部数据都读出来(并存储在其内部),会占用过多的内存,并且速度也会比较慢。

        2. ResultSetDynaClass一次只处理一条记录,在处理完成之前,ResultSet不可以关闭。

        3. ResultSetIterator的next()方法返回的DynaBean其实是指向其内部的一个固定 对象,在每次next()之后,内部的值都会被改变。这样做的目的是节约内存,如果你需要保存每次生成的DynaBean,就需要创建另一个DynaBean,并将数据复制过去,下面也是java doc中的代码:

ArrayList results = new ArrayList(); // To hold copied list 
ResultSetDynaClass rsdc = ...; 
DynaProperty properties[] = rsdc.getDynaProperties(); 
BasicDynaClass bdc = new BasicDynaClass("foo", BasicDynaBean.class,             rsdc.getDynaProperties()); 
Iterator rows = rsdc.iterator(); 
while (rows.hasNext()) { DynaBean oldRow = (DynaBean) rows.next();DynaBean newRow = bdc.newInstance();PropertyUtils.copyProperties(newRow, oldRow);results.add(newRow); 
}

       事实上DynaClass/DynaBean可以用于很多地方,存储各种类型的数据。自己想吧。嘿嘿。

自定义的CustomRowSetDynaClass

       两年前写过一个与RowSetDynaClass目标相同的类,不过多一个功能,就是分页,只取需要的数据,这样内存占用就会减少。先看一段代码:

String driver="com.mysql.jdbc.Driver"; 
String url="jdbc:mysql://localhost/2hu?useUnicode=true&characterEncoding=GBK";  
String username="root"; 
String password="";
Connection con=null; 
PreparedStatement ps=null; 
ResultSet rs=null; 
try { Class.forName(driver).newInstance();con = DriverManager.getConnection(url); ps=con.prepareStatement("select * from forumlist order by name");  rs=ps.executeQuery();/* while(rs.next()){ System.out.println(rs.getString("name")); }rs.beforeFirst();*///第二个参数表示第几页,第三个参数表示页的大小CustomRowSetDynaClass rsdc = new CustomRowSetDynaClass(rs, 2, 5);//RowSetDynaClass rsdc = new RowSetDynaClass(rs); rs.close(); ps.close(); List rows = rsdc.getRows(); for (int i = 0; i <rows.size(); i++) { DynaBean b=(DynaBean)rows.get(i); System.out.println(b.get("name")); } 
} catch (Exception e) { e.printStackTrace();
}finally{try { con.close(); } catch (Exception e) {e.printStackTrace(); } 
}

       在这里用到了一个CustomRowSetDynaClass类,构造方法中增加了page和pageSize两个参数,这样,不管数据库里有多少条记录,最多只取pageSize条记录,若pageSize==-1,则功能和RowSetDynaClass一样。这在大多数情况下是适用的。该类的代码如下:

package com.study.java.utils;import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.apache.commons.beanutils.BasicDynaBean;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaClass;
import org.apache.commons.beanutils.DynaProperty;/**
* @Name: CustomRowSetDynaClass
* @Description: 自定义CustomRowSetDynaClass
* @Author: XXX
* @CreateDate: XXX
* @Version: V1.0*/
public class CustomRowSetDynaClass implements DynaClass, Serializable {protected boolean lowerCase = true;protected int page = 1;protected int pageSize = -1;protected DynaProperty properties[] = null;protected Map propertiesMap = new HashMap();protected List rows = new ArrayList();public CustomRowSetDynaClass(ResultSet resultSet) throws SQLException {this(resultSet, true) ;}public CustomRowSetDynaClass(ResultSet resultSet, boolean lowerCase) throws SQLException {this(resultSet, 1, -1, lowerCase) ;}public CustomRowSetDynaClass(ResultSet resultSet, int i, int j,boolean lowerCase) {if(resultSet ==null) {throw new NullPointerException() ;}this.lowerCase = lowerCase;this.page = page;this.pageSize = pageSize;try {introspect(resultSet);copy(resultSet);} catch (SQLException e) {e.printStackTrace();}}public CustomRowSetDynaClass(ResultSet resultSet, int page, int pageSize) throws SQLException {this(resultSet, page, pageSize, true);}public DynaProperty[] getDynaProperties() {return (properties);}public DynaProperty getDynaProperty(String name) {if (name == null) {throw new IllegalArgumentException("No property name specified");}return ((DynaProperty) propertiesMap.get(name));}public String getName() {return (this.getClass().getName());}public DynaBean newInstance() throws IllegalAccessException,InstantiationException {throw new UnsupportedOperationException("newInstance() not supported");}public List getRows() {return (this.rows);}protected void copy(ResultSet resultSet) throws SQLException {int abs = 0;int rowsCount = 0;int currentPageRows = 0;resultSet.last();rowsCount = resultSet.getRow();if (pageSize != -1) {int totalPages = (int) Math.ceil(((double) rowsCount) / pageSize);if (page > totalPages)page = totalPages;if (page < 1)page = 1;abs = (page - 1) * pageSize;} else {pageSize = rowsCount;if (abs == 0)resultSet.beforeFirst();elseresultSet.absolute(abs);while (resultSet.next() && ++currentPageRows <= pageSize) {DynaBean bean = new BasicDynaBean(this);for (int i = 0; i < properties.length; i++) {String name = properties[i].getName();bean.set(name, resultSet.getObject(name));}rows.add(bean);}}}protected void introspect(ResultSet resultSet) throws SQLException {ArrayList list = new ArrayList();ResultSetMetaData metadata = resultSet.getMetaData();int n = metadata.getColumnCount();for (int i = 1; i <= n; i++) { // JDBC is one-relative!DynaProperty dynaProperty = createDynaProperty(metadata, i);if (dynaProperty != null) {list.add(dynaProperty);}}}
}

这篇关于Common-BeanUtils研究心得的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/990057

相关文章

一种改进的red5集群方案的应用、基于Red5服务器集群负载均衡调度算法研究

转自: 一种改进的red5集群方案的应用: http://wenku.baidu.com/link?url=jYQ1wNwHVBqJ-5XCYq0PRligp6Y5q6BYXyISUsF56My8DP8dc9CZ4pZvpPz1abxJn8fojMrL0IyfmMHStpvkotqC1RWlRMGnzVL1X4IPOa_  基于Red5服务器集群负载均衡调度算法研究 http://ww

生信圆桌x生信分析平台:助力生物信息学研究的综合工具

介绍 少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 生物信息学的迅速发展催生了众多生信分析平台,这些平台通过集成各种生物信息学工具和算法,极大地简化了数据处理和分析流程,使研究人员能够更高效地从海量生物数据中提取有价值的信息。这些平台通常具备友好的用户界面和强大的计算能力,支持不同类型的生物数据分析,如基因组、转录组、蛋白质组等。

开题报告中的研究方法设计:AI能帮你做什么?

AIPaperGPT,论文写作神器~ https://www.aipapergpt.com/ 大家都准备开题报告了吗?研究方法部分是不是已经让你头疼到抓狂? 别急,这可是大多数人都会遇到的难题!尤其是研究方法设计这一块,选定性还是定量,怎么搞才能符合老师的要求? 每次到这儿,头脑一片空白。 好消息是,现在AI工具火得一塌糊涂,比如ChatGPT,居然能帮你在研究方法这块儿上出点主意。是不

研究人员在RSA大会上演示利用恶意JPEG图片入侵企业内网

安全研究人员Marcus Murray在正在旧金山举行的RSA大会上公布了一种利用恶意JPEG图片入侵企业网络内部Windows服务器的新方法。  攻击流程及漏洞分析 最近,安全专家兼渗透测试员Marcus Murray发现了一种利用恶意JPEG图片来攻击Windows服务器的新方法,利用该方法还可以在目标网络中进行特权提升。几天前,在旧金山举行的RSA大会上,该Marcus现场展示了攻击流程,

Science Robotics 首尔国立大学研究团队推出BBEX外骨骼,实现多维力量支持!

重复性举起物体可能会对脊柱和背部肌肉造成损伤,由此引发的腰椎损伤是工业环境等工作场所中一个普遍且令人关注的问题。为了减轻这类伤害,有研究人员已经研发出在举起任务中为工人提供辅助的背部支撑装置。然而,现有的这类装置通常无法在非对称性的举重过程中提供多维度的力量支持。此外,针对整个人体脊柱的设备安全性验证也一直是一个缺失的环节。 据探索前沿科技边界,传递前沿科技成果的X-robot投稿,来自首尔国立

代码随想录训练营day37|52. 携带研究材料,518.零钱兑换II,377. 组合总和 Ⅳ,70. 爬楼梯

52. 携带研究材料 这是一个完全背包问题,就是每个物品可以无限放。 在一维滚动数组的时候规定了遍历顺序是要从后往前的,就是因为不能多次放物体。 所以这里能多次放物体只需要把遍历顺序改改就好了 # include<iostream># include<vector>using namespace std;int main(){int n,m;cin>>n>>m;std::vector<i

BeanUtils.copyProperties()在不同包下,用法不同!!! 切记!!!

用法一: 在import org.springframework.beans.BeanUtils;包下: <span style="white-space:pre"> </span>//赋值vo对象的值到po中 <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span>* <spa

vue原理分析(六)--研究new Vue()

今天我们来分析使用new Vue() 之前研究时,只是说是在创建一个实例。并没有深入进行研究 在vue的源码中找下Vue的构造函数 function Vue(options) {if (!(this instanceof Vue)) {warn$2('Vue is a constructor and should be called with the `new` keyword');}thi

《中国全屋智能行业发展现状与投资前景研究分析报告》

报告导读:本报告从国际全屋智能发展、国内全屋智能政策环境及发展、研发动态、供需情况、重点生产企业、存在的问题及对策等多方面多角度阐述了全屋智能市场的发展,并在此基础上对全屋智能的发展前景做出了科学的预测,最后对全屋智能投资潜力进行了分析。  订购链接:https://www.yxresearch.com/ 第一章全屋智能行业概念界定及发展环境剖析 第一节全屋智能行业相关概念界定 一、智能家

兔子--Android Studio出现错误:Error:Execution failed for task ':myapp:dexDebug'. com.android.ide.common.pro

重点在:finished with non-zero exit value 2. 这里表明了有重复的内容存在。 由于:Android Studio中引入包的方式有如下2种:    compile 'com.android.support:support-v4:22.0.0'    compile files('libs/support-v