2014年3月26日
#
所謂值傳遞,就是說僅將對象的值傳遞給目標對象,就相當于copy;系統將為目標對象重新開辟一個完全相同的內存空間。
所謂引用,就是說將對象在內存中的地址傳遞給目標對象,就相當于使目標對象和原始對象對應同一個內存存儲空間。此時,如果對目標對象進行修改,內存中的數據也會改變。
值傳遞,例如:
class TestT1
{
public static void main(String[] args)
{
int i = 5;
int j = 6;
System.out.println("before exchange i = "+i);//交換前
exchange(i, j);
System.out.println("after exchange i = "+i);//交換后
}
public static void exchange(int a,int b)
{
int k;
k = a;a = b; b = k;
}
}
程序的結果是5!!!
這說明,原始數據類型是按值傳遞的,這個按值傳遞也是指的是進行賦值時的行為。
Java語言明確說明取消了指針,因為指針往往是在帶來方便的同時也是導致代碼不安全的根源,同時也會使程序的變得非常復雜難以理解,但這只是在Java語言中沒有明確的指針定義,實質上每一個new語句返回的都是一個指針的引用。
引用傳遞,例如:
class TestT2
{
public static void main(String[] args)
{
StringBuffer s= new StringBuffer("good");
StringBuffer s2=s;
s2.append(" afternoon.");
System.out.println(s);
}
}
對象s和s2指向的是內存中的同一個地址因此指向的是同一個對象。
這里的意思是進行對象賦值操作是傳遞的是對象的引用,因此對象是按引用傳遞的。
程序運行的輸出是:
good afternoon.
這說明s2和s是同一個對象。
總結:
大家都知道,在JAVA中變量有以下兩種:
基本類型變量,包括boolean、byte、char、short、int、long、float、double。
引用類型變量,包括類、接口、數組(基本類型數組和對象數組)。
對于基本類型和基本類型變量被當作參數傳遞給方法時,是值傳遞。在方法實體中,無法給原變量重新賦值,也無法改變它的值。
而對象作為參數,如果在方法中把對象作為參數,方法調用時,參數傳遞的是對象的引用,即在方法調用時,實際參數把對對象的引用傳遞給形式參數。這是實際參數與形式參數指向同一個地址,即同一個對象,方法執行時,對形式參數的改變實際上就是對實際參數的改變,這個結果在調用結束后被保留了下來。
形參和實參有以下顯著的區別:
1、形參不能離開方法。形參只有在方法內才會發生作用,也只有在方法中使用,不會在方法外可見。而實參可以再程序的任何地方都使用。
2、形參代表一個合集,具有不確定性,而形參代表一個獨立事物,具有確定性(即使是為null)。也就是說,形參不能代表具體的對象,只能代表這些對象共同的屬性(比如超類、各種其他自定義屬性等等),而實參則是具體的對象(比如超類的實例)。
3、形參的值在調用時根據調用者更改,實參則用自身的值更改形參的值(指針、引用皆在此列)
2013年12月31日
#
1.枚舉是jdk5.0以后的全新類,跟class,interface,annotation的級別一樣;關鍵字enum。
2.第一個實例
public enum Color{ //定義
Red,White,Blue;
public static void main(){
Color xx = Color.Red;//使用
}
}
3.enum 提供的常用方法
//兩個常用的靜態方法 values(),valueOf()
for(Color c : c.values()){
System.out.println(c);
}
4.enum 的
構造方法 publc enum Coin{
penney(1),nickel(3),dime(10),quarter(25);
private int value;
public Coin(int value){
this.value=value;
}
public static void main(String args[]){
Coin c = Coin.quarter;
System.out.println(c.getValue());
}
}
5.enum的使用場所
權限控制、游戲方向、需要固定產生類對象的數量
所謂動態代理類是在運行時生成的class,在生成它時,你必須提供一組interface給它,則動態代理類就宣稱它實現了這些 interface。當然,動態代理類就充當一個代理,你不要企圖它會幫你干實質性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作。
下面通過實例來說明:
Subject.java 抽象借口:聲明代理對象和真實對象的共同接口
[java]
public interface Subject {
public void doSomething();
}
public interface Subject {
public void doSomething();
}
RealSubject.java 真實被tb代理對象
[java]
public class RealSubject implements Subject {
@Override
public void doSomething() {
System.out.println("RealSubject.doSomething");
}
}
public class RealSubject implements Subject {
@Override
public void doSomething() {
System.out.println("RealSubject.doSomething");
}
}
DynamicProxy.java 代理對象
[java]
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("Before Invoke ! method : " + method);
//我們可以再代理方法調用前后添加功能
Object result = method.invoke(object, args);
System.out.println("object : " + object + " result : " + result + " args : " + args);
System.out.println("After Invoke !");
return result;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("Before Invoke ! method : " + method);
//我們可以再代理方法調用前后添加功能
Object result = method.invoke(object, args);
System.out.println("object : " + object + " result : " + result + " args : " + args);
System.out.println("After Invoke !");
return result;
}
}
Client.java 測試
[java]
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) throws Exception {
//創建目標對象,也就是被代理對象
RealSubject realSubject = new RealSubject();
//將目標對象交給代理
InvocationHandler handler = new DynamicProxy(realSubject);
// Class proxyClass = Proxy.getProxyClass(Subject.class.getClassLoader()
// , new Class[]{Subject.class});
// Subject subject = (Subject)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
// .newInstance(new Object[]{handler});
//返回代理對象,相當于上面兩句
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
handler);
//叫代理對象去doSomething(),其實在代理對象中的doSomething()中還是會
//用handler來調用invoke(proxy, method, args) 參數proxy為調用者subject(this),
//method為doSomething(),tb參數為方法要傳入的參數,這里沒有
subject.doSomething();
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) throws Exception {
//創建目標對象,也就是被代理對象
RealSubject realSubject = new RealSubject();
//將目標對象交給代理
InvocationHandler handler = new DynamicProxy(realSubject);
// Class proxyClass = Proxy.getProxyClass(Subject.class.getClassLoader()
// , new Class[]{Subject.class});
// Subject subject = (Subject)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
// .newInstance(new Object[]{handler});
//返回代理對象,相當于上面兩句
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
handler);
//叫代理對象去doSomething(),其實在代理對象中的doSomething()中還是會
//用handler來調用invoke(proxy, method, args) 參數proxy為調用者subject(this),
//method為doSomething(),參數為方法要傳入的參數,這里沒有
subject.doSomething();
}
}
打印結果:
Before Invoke ! method : public abstract void Subject.doSomething()
RealSubject.doSomething
object : RealSubject@ec6b00 result : null args : null
After Invoke !
注意:
Java動態代理涉及到的兩個類:
InvocationHandler:該接口中僅定義了一個Object : invoke(Object proxy, Method method, Object[] args);參數proxy指代理類,method表示被代理的方法,args為method中的參數數組,返回值Object為代理實例的方法調用返回的值。這個抽象方法在代理類中動態實現。
Proxy:所有動態代理類的父類,提供用于創建動態代理類和實例的靜態方法。
本文分享了關于Java數組最頂級的11大方法,幫助你解決工作流程問題,無論是運用在團隊環境或是在私人項目中,你都可以直接拿來用!
0. 聲明一個數組(Declare an array)
String[] aArray = new String[5];
String[] bArray = {"a","b","c", "d", "e"};
String[] cArray = new String[]{"a","b","c","d","e"};
1. 在Java中輸出一個數組(Print an array in Java)
int[] intArray = { 1, 2, 3, 4, 5 };
String intArrayString = Arrays.toString(intArray);
// print directly will print reference value
System.out.println(intArray);
// [I@7150bd4d
System.out.println(intArrayString);
// [1, 2, 3, 4, 5]
2. 從數組中創建數組列表(Create an ArrayList from an array)
String[] stringArray = { "a", "b", "c", "d", "e" };
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(stringArray));
System.out.println(arrayList);
// [a, b, c, d, e]
3. 檢查愛淘寶數組中是否包含特定值(Check if an array contains a certain value)
String[] stringArray = { "a", "b", "c", "d", "e" };
boolean b = Arrays.asList(stringArray).contains("a");
System.out.println(b);
// true
4. 連接兩個數組( Concatenate two arrays)
int[] intArray = { 1, 2, 3, 4, 5 };
int[] intArray2 = { 6, 7, 8, 9, 10 };
// Apache Commons Lang library
int[] combinedIntArray = ArrayUtils.addAll(intArray, intArray2);
5. 聲明一個數組內鏈(Declare an array inline )
method(new String[]{"a", "b", "c", "d", "e"});
6. 將數組元素加入到一個獨立的字符串中(Joins the elements of the provided array into a single String)
// containing the provided list of elements
// Apache common lang
String j = StringUtils.join(new String[] { "a", "b", "c" }, ", ");
System.out.println(j);
// a, b, c
7. 將數組列表轉換成一個數組 (Covnert an ArrayList to an array)
String[] stringArray = { "a", "b", "c", "d", "e" };
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(stringArray));
String[] stringArr = new String[arrayList.size()];
arrayList.toArray(stringArr);
for (String s : stringArr)
System.out.println(s);
8. 將數組轉換成一個集合(Convert an array to a set)
Set<String> set = new HashSet<String>(Arrays.asList(stringArray));
System.out.println(set);
//[d, e, b, c, a]
9. 反向數組(Reverse an array)
int[] intArray = { 1, 2, 3, 4, 5 };
ArrayUtils.reverse(intArray);
System.out.println(Arrays.toString(intArray));
//[5, 4, 3, 2, 1]
10. 刪除數組元素(Remove element of an array)
int[] intArray = { 1, 2, 3, 4, 5 };
int[] removed = ArrayUtils.removeElement(intArray, 3);
//create a new array
System.out.println(Arrays.toString(removed));
One more – convert int to byte array
byte[] bytes = ByteBuffer.allocate(4).putInt(8).array();
for (byte t : bytes) {
System.out.format("0x%x ", t);
}
package cc.wshao.util;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GetMacAddress {
public static String callCmd(String[] cmd) {
String result = "" ;
String line = "" ;
try {
Process proc = Runtime.getRuntime().exec(cmd);
InputStreamReader is = new InputStreamReader(proc.getInputStream());
BufferedReader br = new BufferedReader (is);
while ((line = br.readLine ()) != null ) {
result += line;
}
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
*
* @param cmd 第一個命令
* @param another 第二個命令
* @return 第二個命令的執行結果
*/
public static String callCmd(String[] cmd,String[] another) {
String result = "" ;
String line = "" ;
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
proc.waitFor(); // 已經執行完第一個命令,準備執行第二個命令
proc = rt.exec(another);
InputStreamReader is = new InputStreamReader(proc.getInputStream());
BufferedReader br = new BufferedReader (is);
while ((line = br.readLine ()) != null ) {
result += line;
}
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
*
* @param ip 目標ip,一般在局域網內
* @param sourceString 命令處理的結果字符串
* @param macSeparator mac分隔符號
* @return mac地址,用上面的分隔符號表示
*/
public static String filterMacAddress( final String ip, final String sourceString, final String macSeparator) {
String result = "" ;
String regExp = " ((([0-9,A-F,a-f]{1,2} " + macSeparator + " ){1,5})[0-9,A-F,a-f]{1,2}) " ;
Pattern pattern = Pattern.compile(regExp);
Matcher matcher = pattern.matcher(sourceString);
while (matcher.find()){
result = matcher.group( 1 );
if (sourceString.indexOf(ip) <= sourceString.lastIndexOf(matcher.group( 1 ))) {
break ; // 如果有多個IP,只匹配本IP對應的Mac.
}
}
return result;
}
/**
*
* @param ip 目標ip
* @return Mac Address
*
*/
public static String getMacInWindows( final String ip){
String result = "" ;
String[] cmd = {
" cmd " ,
" /c " ,
" ping " + ip
};
String[] another = {
" cmd " ,
" /c " ,
" arp -a "
};
String cmdResult = callCmd(cmd,another);
result = filterMacAddress(ip,cmdResult, " - " );
return result;
}
/**
*
* @param ip 目標ip
* @return Mac Address
*
*/
public static String getMacInLinux( final String ip){
String result = "" ;
String[] cmd = {
" /bin/sh " ,
" -c " ,
" ping " + ip + " -c 2 && arp -a "
};
String cmdResult = callCmd(cmd);
result = filterMacAddress(ip,cmdResult, " : " );
return result;
}
/**
* 獲取MAC地址
* @return 返回MAC地址
*/
public static String getMacAddress(String ip){
String macAddress = "" ;
macAddress = getMacInWindows(ip).trim();
if (macAddress == null || "" .equals(macAddress)){
macAddress = getMacInLinux(ip).trim();
}
return macAddress;
}
/**
* 測試
*/
public static void main(String[] args) {
System.out.println(getMacAddress( " 192.168.10.203 " ));
}
}
摘要: Ehcache 是現在最流行的純Java開源緩存框架,配置簡單、結構清晰、功能強大,最初知道它,是從Hibernate的緩存開始的。網上中文的EhCache材料以簡單介紹和配置方法居多,如果你有這方面的問題,請自行google;對于API,官網上介紹已經非常清楚,請參見官網;但是很少見到特性說明和對實現原理的分析,因此在這篇文章里面,我會詳細介紹和分析EhCache的特性,加上一些自己...
閱讀全文
摘要: jQuery 目前已經成為最流行的JavaScript庫,它可以讓開發者“write less, do more(寫得更少,做得更多)”,這也是它的核心理念。通過它,用戶可以更方便地處理HTML documents、events,更輕松地實現動畫效果、AJAX交互等。 盡管jQuery幫助開發者節省了大量的工作,但是并不是所有的產品都適合使用jQuery。jQu...
閱讀全文
摘要: 泛型的好處: 泛型的主要好處就是讓編譯器保留參數的類型信息,執行類型檢查,執行類型轉換(casting)操作,編譯器保證了這些類型轉換(casting)的絕對無誤。
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.co...
閱讀全文
Log4j ( Log for Java ) 是 Apache 下的一個開源項目,通過 Log4j,可以將程序運行的信息輸送到指定的目的地。這個目的地可以是控制臺、文件、郵箱等。
Log4j 支持兩種格式的文件配置,即 properties 和 xml 兩種格式的文件。下面將要介紹的是采用 properties 格式的配置。
① [ 配置日志級別和輸出源 ]
log4j.rootLogger = 級別,輸出源1,輸出源2 … …
日志信息優先級別 : ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
常用優先級別 : DEBUG < INFO < WARN < ERROR
- DEBUG : 程序的調試信息
- INFO : 程序的一般信息,例如,用戶的登錄、登出,方法執行成功信息等
- WARN : 程序的警告信息
- ERROR : 程序的嚴重錯誤信息,例如,程序的執行拋出異常
Tips : 只有當日志信息的優先級別大于等于配置的日志信息級別,日志信息才會被記錄到日志。
日志輸出源 :
- 日志輸出源的個數可以是一個,也可以是多個,多個輸出源的時候,輸出源與輸出源之間用逗號分隔
- 日志輸出源的名字可以根據需要,自定義起名
② [ 指定輸出源輔助類 ]
log4j.appender.輸出源名稱 = Appender.class
常用的 Appender ( 在 log4j-version.jar 的 org.apache.log4j 包下 ) :
1. org.apache.log4j.FileAppender(文件)
2. org.apache.log4j.ConsoleAppender(控制臺)
3. org.apache.log4j.DailyRollingFileAppender(每天產生一個日志文件)
4. org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件)
③ [ 指定輸出源文件存放路徑 ]
log4j.appender.輸出源名稱.file = path ( 日志具體存放路徑 )
④ [ 指定輸出源文件的格式布局 ]
log4j.appender.輸出源名稱.layout = Layout.class
常用的 Layout ( 在 log4j-version.jar 的 org.apache.log4j 包下 ) :
1. org.apache.log4j.SimpleLayout ( 簡單的布局方式,含日志信息的級別和信息 )
2. org.apache.log4j.PatternLayout ( 可自定義的布局模式 )
3. org.apache.log4j.HTMLLayout ( 以 HTML 方式布局 )
⑤ [ 自定義布局模式,可選 ]
log4j.appender.輸出源名稱.layout.conversionPattern
%p : 輸出日志信息優先級,即DEBUG,INFO,WARN,ERROR,FATAL …
%d : 輸出日志時間點的日期或時間,默認格式為ISO8601,也可以在其后指定格式,例如:%d{yyy-MMM-dd HH:mm:ss},輸出類似:2012-10-10 12:20:18
%r : 輸出自應用啟動到輸出該log信息耗費的毫秒數
%c : 輸出日志信息所屬的類,通常就是所在類的全名
%t : 輸出產生該日志事件的線程名
%l : 輸出日志事件的發生位置
%x : 輸出和當前線程相關聯的信息
%% : 輸出一個"%"字符
%F : 輸出日志消息產生時所在的文件名稱
%L : 輸出代碼中的行號
%m : 輸出代碼中指定的消息,產生的日志具體信息
%n : 換行
[ 轉載出處:http://www.tkk7.com/fancydeepin ]
package cc.wshao.steer.util;
import java.util.Random;
public class StrUtils {
public static final String str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void main(String[] args) {
System.out.print(getString(6));
}
public static String getString(int length) {
StringBuffer sb = new StringBuffer();
Random random = new Random();
for (int i = 0; i < length; i++) {
sb.append(str.charAt(random.nextInt(str.length())));
}
return sb.toString();
}
}