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.blogjava.net/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();
}
}