午后星期午

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、形参的值在调用时根据调用者更改,实参则用自身的值更改形参的值(指针、引用皆在此列)

posted @ 2014-03-26 22:29 午后星期午 阅读(125) | 评论 (0)编辑 收藏

2013年12月31日 #

java枚举

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的使用场所
    权限控制、游戏方向、需要固定产生类对象的数量

posted @ 2013-12-31 14:21 午后星期午 阅读(173) | 评论 (0)编辑 收藏

Java动态代理设计模式

 所谓动态代理类是在运行时生成的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:所有动态代理类的父类,提供用于创建动态代理类和实例的静态方法。

posted @ 2013-12-31 14:07 午后星期午 阅读(108) | 评论 (0)编辑 收藏

Java数组使用实用的技巧

本文分享了关于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);
}

posted @ 2013-12-31 14:07 午后星期午 阅读(92) | 评论 (0)编辑 收藏

通过java获取mac地址

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 " ));
     }
     

}

posted @ 2013-12-31 13:58 午后星期午 阅读(110) | 评论 (0)编辑 收藏

Ehcache详细解读

     摘要: Ehcache  是现在最流行的纯Java开源缓存框架,配置简单、结构清晰、功能强大,最初知道它,是从Hibernate的缓存开始的。网上中文的EhCache材料以简单介绍和配置方法居多,如果你有这方面的问题,请自行google;对于API,官网上介绍已经非常清楚,请参见官网;但是很少见到特性说明和对实现原理的分析,因此在这篇文章里面,我会详细介绍和分析EhCache的特性,加上一些自己...  阅读全文

posted @ 2013-12-31 13:56 午后星期午 阅读(106) | 评论 (0)编辑 收藏

忘掉jQuery,使用JavaScript原生API

     摘要: jQuery 目前已经成为最流行的JavaScript库,它可以让开发者“write less, do more(写得更少,做得更多)”,这也是它的核心理念。通过它,用户可以更方便地处理HTML documents、events,更轻松地实现动画效果、AJAX交互等。  尽管jQuery帮助开发者节省了大量的工作,但是并不是所有的产品都适合使用jQuery。jQu...  阅读全文

posted @ 2013-12-31 13:55 午后星期午 阅读(93) | 评论 (0)编辑 收藏

java 泛型深入

     摘要: 泛型的好处:    泛型的主要好处就是让编译器保留参数的类型信息,执行类型检查,执行类型转换(casting)操作,编译器保证了这些类型转换(casting)的绝对无误。 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.co...  阅读全文

posted @ 2013-12-31 13:45 午后星期午 阅读(99) | 评论 (0)编辑 收藏

log4j 配置

Log4j ( Log for Java ) 是 Apache 下的一个开源项目,通过 Log4j,可以将程序运行的信息输送到指定的目的地。这个目的地可以是控制台、文件、邮箱等。

Log4j 支持两种格式的文件配置,即 properties 和 xml 两种格式的文件。下面将要介绍的是采用 properties 格式的配置。

 log4j.properties 配置示例  


log4j.rootLogger
= INFO, logOutput

log4j.appender.logOutput = org.apache.log4j.FileAppender

log4j.appender.logOutput.file = src/main/resources/log/demoLog.log

log4j.appender.logOutput.layout = org.apache.log4j.PatternLayout

log4j.appender.logOutput.layout.conversionPattern = %n%n%d{yyyy-MM-dd HH:mm:ss}%n%p  %c  %L%n%m



① [ 配置日志级别和输出源 ]

      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.blogjava.net/fancydeepin ]

posted @ 2013-12-31 13:27 午后星期午 阅读(104) | 评论 (0)编辑 收藏

Java生成随机字符串

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();
 }

}

posted @ 2013-12-31 13:22 午后星期午 阅读(113) | 评论 (0)编辑 收藏

仅列出标题  下一页