利用java反射机制实现对象值拷贝

首先需求是这样的 ,我把它简化一下:

User user1=new User();
user1.setUserName("wxn");
User user2=new User();
user2.setUserName("kkkk");
User user3=user2;

接下来的操作我想让user2中的值和user1中的值全部相等。我们知道可以通过 user2=user1.clone()方法去获得一个新的对象,这种方法的详细介绍在这里可以学习。http://www.cnblogs.com/yxnchinahlj/archive/2010/09/20/1831615.html

但是这样clone出来的是一个新的对象,user2就是user1的一个新对象的拷贝,虽然user2中的值可以和user1中的值相等,但是 user3就已经不是user2之前的对象了,我需要user3中的值也跟着改变。

于是最简单的方法就是在User类中增加一个方法

public void copy(User user){
    this.setUserName(user.getUserName);
    this.setUserId(user.setUserId);
     .....
}

如果user中的属性太多怎么办?那写起来太麻烦了,除了方法名get和set有区别之外没什么区别, 于是我想起了之前看过的java反射机制来批量处理,顺便巩固一下java的反射机制,实现代码如下

public void copy(User user) {
//获得User类中所有的方法
		Method[] methods = user.getClass().getMethods();
		try {
		for (int i = 0; i < methods.length; i++) {
				String mName = methods[i].getName();
				if (mName.startsWith("set")) {
					String nName =null;
					//若为boolean的属性则没有get方法 只有 isXXX方法
					 if(boolean.class.equals(methods[i].getParameterTypes()[0]) ){
						  nName=mName.replace("set", "is");
					  }	else{
						  nName=mName.replace("set", "get");
					  }
					Method method = user.getClass().getDeclaredMethod(nName,
							null);
					methods[i].invoke(this, method.invoke(user, null));
				}

			} 
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

全部代码如下


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 
 * @author ahsiu
 * 
 */

public class User {
	private int userId;
	private String userName;
	private String password;
	private String email;
	private String phone;
	private int loginState;
   private boolean flag;
	public int getUserId() {
		return userId;
	}

	public void copy(User user) {
		Method[] methods = user.getClass().getMethods();
		try {
			for (int i = 0; i < methods.length; i++) {
				String mName = methods[i].getName();
				if (mName.startsWith("set")) {

					String nName =null;
					//若为boolean的属性则没有get方法 只有 isXXX方法
					 if(boolean.class.equals(methods[i].getParameterTypes()[0]) ){
						  nName=mName.replace("set", "is");
					  }	else{
						  nName=mName.replace("set", "get");
					  }

					Method method = user.getClass().getDeclaredMethod(nName,
							null);
					methods[i].invoke(this, method.invoke(user, null));

				}

			}
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void setUserId(int userId) {
		this.userId = userId;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public int getLoginState() {
		return loginState;
	}

	public void setLoginState(int loginState) {
		this.loginState = loginState;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	public static void main(String[] args) {
		User user1=new User();
		user1.setUserName("wxn");
		User user2=new User();
		user2.setUserName("kkkk");
		User user3=user2;
		System.out.println(user1.getUserName());
		System.out.println(user2.getUserName());
		System.out.println(user3.getUserName());	
		System.out.println("");
		user2.copy(user1);
		System.out.println(user1.getUserName());
		System.out.println(user2.getUserName());
		System.out.println(user3.getUserName());
		System.out.println("");
		user3.setUserName("ahsiu");
		System.out.println(user1.getUserName());
		System.out.println(user2.getUserName());
		System.out.println(user3.getUserName());
	}
}

[转]android解决图片加载oom的方法

大家好,今天给大家分享的是解决解析图片的出现oom的问题,我们可以用BitmapFactory这里的各种Decode方法,如果图片很小的话,不会出现oom,但是当图片很大的时候

就要用BitmapFactory.Options这个东东了,Options里主要有两个参数比较重要.

  1. options.inJustDecodeBounds = false/true;
  2. //图片压缩比例.
  3. options.inSampleSize = ssize;

我们去解析一个图片,如果太大,就会OOM,我们可以设置压缩比例inSampleSize,但是这个压缩比例设置多少就是个问题,所以我们解析图片可以分为俩个步骤,第一步就是

获取图片的宽高,这里要设置Options.inJustDecodeBounds=true,这时候decode的bitmap为null,只是把图片的宽高放在Options里,然后第二步就是设置合适的压缩比例inSampleSize,这时候获得合适的Bitmap.这里我画了简单的流程图,如下:

 

为了让大家更容易理解,我这里做了一个简单的demo,主要功能就是一个界面里有个ImageView,点击ImageView的时候,进入本地相册,选择一个图片的时候,ImageView控件显示选择的图片。Demo的步骤如下:

第一步新建一个Android工程命名为ImageCacheDemo.目录结构如下:

第二步新建一个ImageCacheUtil.java工具类,代码如下:

 

  1. package com.tutor.oom;
  2. import java.io.InputStream;
  3. import android.content.ContentResolver;
  4. import android.content.Context;
  5. import android.graphics.Bitmap;
  6. import android.graphics.BitmapFactory;
  7. import android.graphics.BitmapFactory.Options;
  8. import android.net.Uri;
  9. /**
  10.  * @author frankiewei.
  11.  * 工具类.
  12.  */
  13. public class ImageCacheUtil {
  14.     /**
  15.      * 获取合适的Bitmap平时获取Bitmap就用这个方法吧.
  16.      * @param path 路径.
  17.      * @param data byte[]数组.
  18.      * @param context 上下文
  19.      * @param uri uri
  20.      * @param target 模板宽或者高的大小.
  21.      * @param width 是否是宽度
  22.      * @return
  23.      */
  24.     public static Bitmap getResizedBitmap(String path, byte[] data,
  25.             Context context,Uri uri, int target, boolean width) {
  26.         Options options = null;
  27.         if (target > 0) {
  28.             Options info = new Options();
  29.             //这里设置true的时候,decode时候Bitmap返回的为空,
  30.             //将图片宽高读取放在Options里.
  31.             info.inJustDecodeBounds = false;
  32.             decode(path, data, context,uri, info);
  33.             int dim = info.outWidth;
  34.             if (!width)
  35.                 dim = Math.max(dim, info.outHeight);
  36.             int ssize = sampleSize(dim, target);
  37.             options = new Options();
  38.             options.inSampleSize = ssize;
  39.         }
  40.         Bitmap bm = null;
  41.         try {
  42.             bm = decode(path, data, context,uri, options);
  43.         } catch(Exception e){
  44.             e.printStackTrace();
  45.         }
  46.         return bm;
  47.     }
  48.     /**
  49.      * 解析Bitmap的公用方法.
  50.      * @param path
  51.      * @param data
  52.      * @param context
  53.      * @param uri
  54.      * @param options
  55.      * @return
  56.      */
  57.     public static Bitmap decode(String path, byte[] data, Context context,
  58.             Uri uri, BitmapFactory.Options options) {
  59.         Bitmap result = null;
  60.         if (path != null) {
  61.             result = BitmapFactory.decodeFile(path, options);
  62.         } else if (data != null) {
  63.             result = BitmapFactory.decodeByteArray(data, 0, data.length,
  64.                     options);
  65.         } else if (uri != null) {
  66.             //uri不为空的时候context也不要为空.
  67.             ContentResolver cr = context.getContentResolver();
  68.             InputStream inputStream = null;
  69.             try {
  70.                 inputStream = cr.openInputStream(uri);
  71.                 result = BitmapFactory.decodeStream(inputStream, null, options);
  72.                 inputStream.close();
  73.             } catch (Exception e) {
  74.                 e.printStackTrace();
  75.             }
  76.         }
  77.         return result;
  78.     }
  79.     /**
  80.      * 获取合适的sampleSize.
  81.      * 这里就简单实现都是2的倍数啦.
  82.      * @param width
  83.      * @param target
  84.      * @return
  85.      */
  86.     private static int sampleSize(int width, int target){
  87.             int result = 1;
  88.             for(int i = 0; i < 10; i++){
  89.                 if(width < target * 2){
  90.                     break;
  91.                 }
  92.                 width = width / 2;
  93.                 result = result * 2;
  94.             }
  95.             return result;
  96.         }
  97. }

第三步:修改ImageCacheDemoActivity.java代码如下:

 

 

  1. package com.tutor.oom;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.graphics.Bitmap;
  5. import android.os.Bundle;
  6. import android.provider.MediaStore;
  7. import android.view.View;
  8. import android.view.View.OnClickListener;
  9. import android.widget.ImageView;
  10. /**
  11.  * @author frankiewei.
  12.  * 解决图片普通OOM的Demo.
  13.  */
  14. public class ImageCacheDemoActivity extends Activity {
  15.     /**
  16.      * 显示图片的ImageView.
  17.      */
  18.     private ImageView mImageView;
  19.     /**
  20.      * 打开本地相册的requestcode.
  21.      */
  22.     public static final int OPEN_PHOTO_REQUESTCODE =  0x1;
  23.     /**
  24.      * 图片的target大小.
  25.      */
  26.     private static final int target = 400;
  27.     @Override
  28.     public void onCreate(Bundle savedInstanceState) {
  29.         super.onCreate(savedInstanceState);
  30.         setContentView(R.layout.main);
  31.         setupViews();
  32.     }
  33.     private void setupViews(){
  34.         mImageView = (ImageView)findViewById(R.id.imageview);
  35.         mImageView.setOnClickListener(new OnClickListener() {
  36.             public void onClick(View v) {
  37.                 openPhotos();
  38.             }
  39.         });
  40.     }
  41.     /**
  42.      * 打开本地相册.
  43.      */
  44.     private void openPhotos() {
  45.         Intent intent = new Intent(Intent.ACTION_PICK, null);
  46.         intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
  47.                 “image/*”);
  48.         startActivityForResult(intent, OPEN_PHOTO_REQUESTCODE);
  49.     }
  50.     @Override
  51.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  52.         switch (requestCode) {
  53.         case OPEN_PHOTO_REQUESTCODE:
  54.             if(resultCode == RESULT_OK){
  55.                 //如果用这个方法,Options为null时候,就是默认decode会出现oom哦.
  56.                 //Bitmap bm = ImageCacheUtil.decode(null, null,
  57.                 //      ImageCacheDemoActivity.this, data.getData(), null);
  58.                 //这里调用这个方法就不会oom.屌丝们就用这个方法吧.
  59.                 Bitmap bm = ImageCacheUtil.getResizedBitmap(null, null,
  60.                         ImageCacheDemoActivity.this, data.getData(), target, false);
  61.                 mImageView.setImageBitmap(bm);
  62.             }
  63.             break;
  64.         default:
  65.             break;
  66.         }
  67.         super.onActivityResult(requestCode, resultCode, data);
  68.     }
  69. }

其中main.xml布局代码如下:

 

 

  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
  3.     android:layout_width=”fill_parent”
  4.     android:layout_height=”fill_parent”
  5.     android:orientation=”vertical” >
  6.     <TextView
  7.         android:layout_width=”fill_parent”
  8.         android:layout_height=”wrap_content”
  9.         android:text=”@string/hello” />
  10.     <ImageView
  11.         android:id=”@+id/imageview”
  12.         android:layout_width=”400px”
  13.         android:layout_height=”400px”
  14.         android:src=”@drawable/ic_launcher”
  15.         />
  16. </LinearLayout>

 

第四步运行上述工程,效果如下:

从本地相册选择显示。用了getRsizedBitmap()方法,图片很大不会oom.

 

运用默认的decode方法就会oom。

OK,今天就讲到这里,大家有什么疑问的,可以留言,谢谢大家!!!

源代码点击进入==>