JAVA編程思想,最近主要學習對象和引用的關係。
在內存中,引用主要存放在堆棧中,而JAVA對象主要存放在堆中。
在堆棧中方便管理儲存分配與清理,而在堆中的數據,編譯器並不需要知道其存活的週期,有JVM的垃圾回收機制進行統一管理。
基本類型,並不是創建引用,而是直接在堆棧中進行保存,比較高效;但是其封裝類必須是會創建引用的。
同時這裏又引出了基本類型的自動裝箱和自動拆箱的概念,如下:
Integer a = new Integer(8);
Integer b = new Integer(8);
int c = 8;
int d = 8;
System.out.println(a == b);//false;
System.out.println(a == c);//true;
System.out.println(d == c);//true;
那麼上面代碼的對象a和對象b如何比較呢,應該通過
a.equals(b);//true
來進行比較。
這是因爲int的封裝類Integer,重寫了equals的比較方法。
如果是自定義的類,而且沒有重寫equals方法的話
public class JDKTest {
/**
* 功能描述: <br>
* 〈功能詳細描述〉
*
* @param args
* @see [相關類/方法](可選)
* @since [產品/模塊版本](可選)
*/
public static void main(String[] args) {
Value v1 = new Value();
Value v2 = new Value();
v1.i = v2.i = 100;
System.out.println(v1.equals(v2));//false;
}
}
class Value{
int i;
}
重寫equals方法後
public class JDKTest {
/**
* 功能描述: <br>
* 〈功能詳細描述〉
*
* @param args
* @see [相關類/方法](可選)
* @since [產品/模塊版本](可選)
*/
public static void main(String[] args) {
Value v1 = new Value();
Value v2 = new Value();
v1.i = v2.i = 100;
System.out.println(v1.equals(v2));//true;
}
}
class Value{
int i;
@Override
public boolean equals(Object arg0) {
if(this == arg0){
return true;
}
if(! (arg0 instanceof Value) ){
return false;
}
else if(this.i == ((Value)arg0).i){
return true;
}
else {
return false;
}
}
}
同時參數的傳遞,如果不是基本類型,傳遞的也是引用
public class JDKTest {
static void f(Letter y){
y.c = 'Z';
}
/**
* 功能描述: <br>
* 〈功能詳細描述〉
*
* @param args
* @see [相關類/方法](可選)
* @since [產品/模塊版本](可選)
*/
public static void main(String[] args) {
Letter x = new Letter();
x.c = 'a';
System.out.println(x.c);
f(x);
System.out.println(x.c);
}
}
class Letter{
char c;
}
輸出的結果:
a
Z
都是引用,更新的都是堆中對象的值,同時所有對這個對象的引用的值都會改變(因爲只是“引用而已”)。
如果需要傳遞對象而不是傳遞對象的引用的話,就需要重新new一個新的對象,並把原對象中的值賦給新的對象。
Letter x = new Letter();
x.c = 'a';
Letter y = new Letter();
y.c = x.c;//通過這種方式傳遞值
補充:
找了下,發現已經有工具類可以實現這個功能(需要jar包commons-beanutils-1.8.3.jar)
org.apache.commons.beanutils.BeanUtils.copyProperty(Object bean, String name, Object value)
throws IllegalAccessException, InvocationTargetException;
T t;
try {
t = clazz.newInstance();
for (Field field : fields) {
List<String> fieldValues = map.get(field.getName());
if (fieldValues != null && fieldValues.size() > 0) {
if(field.getType().getName().equals("java.math.BigDecimal")){
if(!"".equals(fieldValues.get(0))){
BeanUtils.copyProperty(t, field.getName(), fieldValues.get(0));
}
}else {
BeanUtils.copyProperty(t, field.getName(), fieldValues.get(0));
}
}
}
} catch (Exception e) {
return null;
}
return t;
以下內容轉自他人博客:apache.commons.beanutils.BeanUtils的使用
該class提供了一系列的靜態方法操作業已存在的符合JavaBean規範定義的Java Class.這裏強調的JavaBean規範,簡單來說就是一個Java Class通過一系列getter和setter的方法向外界展示其內在的成員變量(屬性).通過BeanUtils的靜態方法,我們可以:
- 複製一個JavaBean的實例--BeanUtils.cloneBean();
- 在一個JavaBean的兩個實例之間複製屬性--BeanUtils.copyProperties(),BeanUtils.copyProperty();
- 爲一個JavaBean的實例設置成員變量(屬性)值--BeanUtils.populate(),BeanUtils.setProperty();
- 從 一個一個JavaBean的實例中讀取成員變量(屬性)的值 --BeanUtils.getArrayProperty(),BeanUtils.getIndexedProperty(),BeanUtils.getMappedProperty(),BeanUtils.getNestedProperty(),BeanUtils.getSimpleProperty(),BeanUtils.getProperty(),BeanUtils.describe();
總的來看BeanUtils類提供了兩大類的功能:讀,寫成員變量.