BloveSaga

在希腊帕尔纳斯山南坡上,有一个驰名世界的戴尔波伊神托所,在它的入口处的巨石上赫然锈刻着这样几个大字: 认识你自己!

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  34 随笔 :: 12 文章 :: 119 评论 :: 0 Trackbacks

2006年6月5日 #

匹配中文字符的正则表达式:  [\u4e00-\u9fa5]

匹配双字节字符 ( 包括汉字在内 ) [^\x00-\xff]

应用:计算字符串的长度(一个双字节字符长度计 2 ASCII 字符计 1

String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}

匹配空行的正则表达式: \n[\s| ]*\r

匹配 HTML 标记的正则表达式: /<(.*)>.*<\/\1>|<(.*) \/>/ 

匹配首尾空格的正则表达式: (^\s*)|(\s*$)

应用: javascript 中没有像 vbscript 那样的 trim 函数,我们就可以利用这个表达式来实现,如下:

String.prototype.trim = function()
{
return this.replace(/(^\s*)|(\s*$)/g, "");
}

利用正则表达式分解和转换 IP 地址:

下面是利用正则表达式匹配 IP 地址,并将 IP 地址转换成对应数值的 Javascript 程序:

function IP2V(ip)
{
re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //
匹配 IP 地址的正则表达式
if(re.test(ip))
{
return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1
}
else
{
throw new Error("Not a valid IP address!")
}
}

不过上面的程序如果不用正则表达式,而直接用 split 函数来分解可能更简单,程序如下:

var ip="10.100.20.168"
ip=ip.split(".")
alert("IP
值是: "+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))

匹配 Email 地址的正则表达式: \w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

匹配网址 URL 的正则表达式: http://( [\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?

利用正则表达式去除字串中重复的字符的算法程序: [ 注:此程序不正确,原因见本贴回复 ]

var s="abacabefgeeii"
var s1=s.replace(/(.).*\1/g,"$1")
var re=new RegExp("["+s1+"]","g")
var s2=s.replace(re,"") 
alert(s1+s2) //
结果为: abcefgi

这个方法对于字符顺序有要求的字符串可能不适用。

得用正则表达式从 URL 地址中提取文件名的 javascript 程序,如下结果为 page1

s="http://www.9499.net/page1.htm"
s=s.replace(/(.*\/){0,}([^\.]+).*/ig,"$2")
alert(s)

利用正则表达式限制网页表单里的文本框输入内容:

用正则表达式限制只能输入中文: onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))"

用正则表达式限制只能输入全角字符:  onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))"

用正则表达式限制只能输入数字: onkeyup="value=value.replace(/[^\d]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"

用正则表达式限制只能输入数字和英文: onkeyup="value=value.replace(/[\W]/g,'') "onbeforepaste="clipboardData.setData

几个常用正则表达式:
('text',clipboardData.getData('text').replace(/[^\d]/g,''))" 
Email : /^\w+([-+.]\w+)*@\w+([-.]\\w+)*\.\w+([-.]\w+)*$/,    
Phone : /^((\(\d{3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}$/,    
Mobile : /^((\(\d{3}\))|(\d{3}\-))?13\d{9}$/,    
Url : /^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/,    
IdCard : /^\d{15}(\d{2}[A-Za-z0-9])?$/,    
Currency : /^\d+(\.\d+)?$/,
Number : /^\d+$/,    
Zip : /^[1-9]\d{5}$/,    
QQ : /^[1-9]\d{4,8}$/,    
Integer : /^[-\+]?\d+$/,    
Double : /^[-\+]?\d+(\.\d+)?$/,    
English : /^[A-Za-z]+$/,    
Chinese :  /^[\u0391-\uFFE5]+$/,    
UnSafe :/^(([A-Z]*|[a-z]*|\d*|[-_\~!@#\$%\^&\*\.\(\)\[\]\{\}<>\?\\\/\'\"]*)|.{0,5})$|\s/,

posted @ 2006-06-05 22:40 蓝色Saga 阅读(122) | 评论 (0)编辑 收藏

     摘要: 正则表达式是一个描述字符模式的对象。 JavaScript 的 RegExp 对象和 String 对象定义了使用正则表达式来执行强大的模式匹配和文本检索与替换函数的方法 .'***********************'              \\JavaScript//''***************...  阅读全文
posted @ 2006-06-05 22:37 蓝色Saga 阅读(414) | 评论 (0)编辑 收藏

JavaScript语法

什么是脚本程序和JavaScript

 *什么是脚本程序
 <html>
 <script language="javascript">
    alert(new Date());
 </script>
 </html>

 *JavaScript简介
  前身叫作Livescript,是一种基于对象(Object)和事件驱动(Event Driver),并具有安全性能的脚本语言.
 *JavaScript与Java
  是两个公司开发的两个不同产品,作用与用途大不一样,但两者语法上有很多相似之处,JavaScript并不是
  Java的子集.
 *JavaScript,JScript与ECMAScript
 *脚本代码的位置
  我们可以把代码放到<script></script>标签之间:
  <script>
    var x=3;
  </script>
  <p>This is a HTML 段落</p>
  <script>
    alert(x);
  </script>
  也可以放在一个单独的文件中:
  <html>
  <script src="script.js" language="javascript">
 *将脚本程序代码作为属性值
  <a href="javascript:alert(new Data());">javascript</a>
  </html>
=======================================================================================
JavaScript的基本语法

 *JavaScript中的标识符
 标识符是指JavaScript中定义的符号,例如,变量名,函数名,数组名等.标识符可以由任意顺序的
 大小写字母,数字,下划线(_)和美元符号($)组成,但标识符不能以数字开头,不能是JavaScript
 中的保留关键字.
 合法的标识符举例: indentifler,username,user_name,_username,$username
 非法的标识符举例: int,98.3,Hello World
 *Java严格区分大小写
 computer和Computer是两个完全不同的标识符
 *JavaScript程序代码格式
 每条功能语句的最后必须用分号(;)结束,每个词之间用空格,制表符,换行符或大括号,小括号这样
 的分隔符隔开.
 *JavaScript程序的注释
 /*...*/中可以嵌套"//"注释,但不能嵌套"/"...."/".

================================================================================
基本数据类型与常量

 *正型常量
 十六进制以Ox或OX开头,例如:Ox8a.八进制必须以O开头,例如: 0123.十进制的第一位不能为0
 (数字0除外),例如: 123
 *字符常量
 12.32,123.42,5E7,4e5等.
 *布尔值
 true和false.
 *字符串常量
 例如: "a book of JavaScript",'abc',"a",""(空字符串) .
 特殊字符需要用反斜杠(\)来转意.
 例如: \r, \n, \t, \b, \', \\
 在JavaScript中一个连续的字符串不能分开在两行中来写.可以使用"+"号连起来.
 *null常量
 表示变量的值为空
 *undefined常量
 表示一个变量还没有被复值时的状态,或某个对象的属性不存在.

=========================================================================================
变量

 *定义一个变量,系统就会为之分配一块内存,程序可以用变量名来表示这块内存中的数据.
 *声明变量用var关键字
 例如: var x; (这个时候就是undifeined)
 *声明变量的同时为其赋值
 例如: var name="lisi";
 *对已赋值的变量赋于一个其他类型的数据
 例如: name=123;
 *不事先声明变量而直接使用
 例如: x=1234;

算术运算符

 *+ 加法运算符或正值运算符,例如, x+5, +6.
  它还能实现多个字符串的想加,也能将字符串与其他的数据类型连成一个新的字符串,条件
  条件是该表达式中至少有一个字符串,例如: "x"+123的结果为"x123".
 *- 减法运算符或负预算符,例如, 7-3, -8.
 ** 乘法运算符,例如, 3*7.
 */ 除法运算符,例如 9/4.
 *% 求模运算符(算术中的求余),例如, 5%2
 *++将变量值加1后再将结果赋给这个变量,分为两种,例如a++和++a
 *--用法与++预算符一样
 

赋值运算符
 
  赋值运算符的作用是将一个值赋给一个变量,最常用的是"=",还可以由"="运算符和其他的一些
  预算符组合成新的运算符,例如:
  "+=","-="等.

比较运算符

  *>大于
   当左边的操作数大于右边的操作数时,返回true.
  *<小与
  *=
  *<=
  *>=
  *==
  *!=
  注意: 不要把"=="写成"="

逻辑运算符
 
  *&&
  逻辑与,当左右两边的操作数都为true时,返回值为true,否则为false.
  *||
  逻辑或,当左右两边的操作数都为false时,返回值为false,否则为true.
  *!
  逻辑非,当操作数为ture的时,返回值为false,否则为true.

========================================================================
程序流程控制
 
 *顺序结构
 *if条件选择语句
 *switch选择语句
 *while循环语句
 *do while语句
 *for循环语句
 *break与continue语句

 if条件语句语法1:
 if(条件语句)
 {
   执行语句块
 }
 注意:if(x==null)或if(typeof(x)=="undefined")可以简写成if(!x)
 if条件语句语法2:
 if(条件语句)
 {
   执行语句块1
 }
 else
 {
   执行语句块2
 }
 变量=布尔表达式? 语句1 :语句2
 if条件语句语法3:
 if(条件语句)
 {
   执行语句块1
 }
 else if(条件语句2)
 {
   执行语句块2
 }
 ....
 else if(条件语句块n)
 {
   执行语句块n
 }
 else
 {
   执行语句块n+1
 }
 if语句块的嵌套
 if(x<1)
 {
  if(y==1)
    alert("x<1,y==1");
  else
    alert("x<1,y!=1");
  }
  else if(x>10)
  {
    if(y==1)
      alert("x>10,y==1);
    else
      alert("x>10,y!=1");  
  }

===================================================================
函数
 
 *函数的作用与定义
 *全局变量与局部变量
 *参数个数可变的函数
 *创建动态函数
 *JavaScript中的系统函数

  定义一个函数的语法如下:
  function 函数名 (参数列表)
  {
     程序代码
     return 表达式;
  }
  对函数调用的几种方式:
  1.函数名(传递函数的参数1,传递给函数的参数2,.....)
  2.变量=函数名(传递函数的参数1,传递给函数的参数2,.....)
  3.对于有返回值的函数调用,也可以在程序中直接使用返回结果,例如:
  alert("sum="+square(2,3));

  全局变量与局部变量,看下面的代码:
  <script language="javascript">
   var msg="全局变量";
   function show()
   {
      msg="局部变量";
   }
   show();
   alert(msg);
  </script>

  参数个数可变的的函数:
 <script language="javascript">
  function testparams()
  {
    var params="";
    for(var i=0;i<arguments.length;i++)
    {
      params +=" "+ arguments[i];
    }
    alert(params);
  }
    testparams("abc",123);
    testparams(123,456,"abc");
 </script>
  注意:arguments代表了传递给函数的所有参数的所有集合。当函数的个数不确定,
  获得参数个数很多,你又不想为每个参数定义一个变量,那么你就可以定义一个
  像上面那个一样的,定义一个为空的参数名,在内部用循环来实现。
 创建动态函数的语法:
 var varName=new Function(argument1,....,lastArgument);
 说明:
 所有的参数都必须是字符串型的,最后的参数必须是这个动态函数的功能程序代码.
 例子:
 <script>
   var square=new Function("x","y",
            "var sum;sum=x*x+y*y; return sum;");
   alert(square(3,2));
 </script>
 动态函数有什么作用,在什么情况下使用?
 
 JavaScript中的系统函数:
 .encodeURI方法(比URL的描述的范围更大,一般情况下可以等同)
 返回一个URI字符串编码后的效果。例如:
 <script language="javascript">
   var uriStr=encodeURI("http://www.doit.org/index.html?country=中国&name=z x");
   alert(uriStr);
 </script>

 .decodeURI方法
 将一个已编码的URI字符串解码成最初的字符串并返回.
 .parseInt方法
  第一字符串按指定的进制转换成一个整数,语法格式为:parseInt(numString,[redix])。
  如果没有指定第二个参数,则前缀为'Ox'的字符串被视为十六进制,前缀为'O'的字符串
  被视为八进制,所有其他的字符串被视为十进制。
  例如: alert(parseInt("123abc",10));
 .parseFloat方法
  将一个字符串转换为小数。
 .isNaN方法(用与检测)
 .escape方法(用于对文本的简单加密)
  返回对一个字符串进行编码后的结果字符串。所有空格,标点,重音符号以及任何其他
  ASCII字符都用%xx编码替换,其中xx等于表示该字符的Unicode编码的十六进制数,字符
  值大于255字符以%uxxxx格式表示。
 .unescape方法
  将一个用escape方法编码的字符串解码成原始字符串。
 .eval方法
  将其中的参数字符串作为一个JavaScript表达式执行。

=======================================================================
  对象
 *对象与对象实例
 *构造方法与this关键字的作用
 *在函数中修改参数值的问题

 对象与对象实例
 .对象中所包含的变量就是对象的属性,对象中所包含的对属性进行操作的函数就是对象的
  方法,对象的属性和方法都叫对象的成员。
 .对象是某一类事物的描述,是抽象的概念;而对象实例是一类事物中的具体个例。
 .能够被用来创建对象实例的函数就是对象的构造函数,只要定义一个对象的构造函数,就
  等于被定义了一个对象。使用new关键字和对象的构造函数就可以创建对象实例,语法格式
  如下: var ObjectInstance = new ObjName(传递给该对象的实际参数列表)。
  <script language="javascript">
  function Person()
  {
    //这是一个构造函数
  }
  var person1 = new Person();  //创建了一个实例变量(对象实例)
  person1.age = 18;
  person1.name = "blovesaga"; //age和name为对象属性
  //alert(person1.name+"."+person1.age);
  function sayFunc()
  {
    alert(person1.name+"."+person1.age);//我们也可以使用person["age"](对象实例["成员变量"])来访问
  }
  person1.say=sayFunc;  //把方法名赋值给了person1.say成员,我们可以在其他地方像
                        //调用方法一样来调用
  person1.say();
  </script>

看下面的例子:
<html>
 <script language="javascript">
   //定义一个构造函数,也就是对象的名称为person
   function Person()
   {
   }
   //创建一个对象实例
   var person1=new Person();
   person1.age=18;
   person1.name="zxy";
   //编写一个成员方法
   function sayFunc()
   {
      var x="name";
      eval("alert(person1."+ x + ");");  //这个字符串中的内容将被作为JavaScipt代码来执行
      alert(person1.name+":"+person1.age);
   }
   person1.say=sayFunc; //把方法名赋值给了person1.say成员
   person1.say=sayFunc(); //写了括号表示执行sayFunc()函数在复值
   person1.say();
 </script>
</html>

===================================================================
构造方法与this关键字

 .为一个对象实例新增加的属性和方法,不会增加到同一个对象所产生的其它对象实例上。
 .所有的实例对象在创建都会自动调用构造函数,在构造函数中增加的属性和方法会被
  增加到每个对象实例上。
 .对象实例是使用new关键字创建的,在构造方法中不要有返回结果的return语句。
 .调用对象的成员方法时,需要使用“对象实例.成员方法"的形式,很显然,用作成
  员方法的函数被调用,一定伴随有某个对象实例。this关键字代表某个成员方法执行时
   ,引用该方法的当前对象实例,所以,this关键字一般只在用作对象成员方法的
  函数中出现。
  <script language="javascript">
   function Person(name,age)
   {
     this.age=age;
     this.name=name;
     this.say=sayFunc;
   }
   function sayFunc()
   {
      alert(this.name+":"+this.age);
   }
   var person1=new Person("张山",18);
   person1.say();
   var person2 = new Person("里四",30);
   person2.say();
  </script>
例子代码:
<html>
 <script language="javascript">
   //定义一个构造函数
   function Person(name,age)
   {
     this.name=name;//当前的对象实例增加一个成员变量name,成员变量的通过Person()参数name传递进来
     this.age=age;//当前的对象实例增加一个成员变量age,成员变量的通过Person()参数age传递进来
     this.say=sayFunc; //增加一个sayFunc()函数
   }
   function sayFunc()
   {
     alert(this.name + ":" + this.age);
   }
   //创建一个对象实例
   var person1=new Person("张三",18);
   person1.say();  //调用person1的say()成员方法
   var person2=new Person("李四",29);
   person2.say();  //调用person2的say()成员方法
 </script>
</html>

=====================================================================
在函数中修改参数值的问题

 将基本数据类型的变量作为函数参数传递的情况:
 <script language="javascript">
  function changeValue(x)
  {
    x=5;
  }
  var x=3;
  changeValue(x);
  alert(x);
 </script>
注意: 在函数changeValue(x)中的x=5并不能修改主程序中的x值,函数接受的参数
就相当于一个局部变量,当函数调用完也就没用了。所以该程序的结果为x=3;如果
我们把一个对象的实例传递给函数,而我们有在函数中修改了对象实例的属性,那么
最后的结果也会变化的。

posted @ 2006-06-05 22:34 蓝色Saga 阅读(147) | 评论 (0)编辑 收藏

     摘要: JAVA 程序员面试 32 问 第一,谈谈 final , ...  阅读全文
posted @ 2006-06-05 15:16 蓝色Saga 阅读(212) | 评论 (2)编辑 收藏

>>>>>>>>>>>>>>>>Runtime和Process类<<<<<<<<<<<<<<<<<<<
1> 每一个Java程序都有一个Runtime类的单一实例。
2> 通过Runtime.getRuntime()获取Runtime类的实例。
3> Runtime类是使用单例模式的一个例子。
   Runtime没有public的构造方法。我们必须用Runtime的静态方法getRuntime();我们可以用
   Runtime的exec来执行一个外部程序,也可以用来编译一个源文件(用来做图形界面的编译器)。
import java.io.*;
class RuntimeTest
{
 public static void main(String[] args)
 {
  Runtime rt=Runtime.getRuntime();
  //System.out.println(rt.freeMemory());
  try
  {
   //rt.exec("notepad");
   Process p=rt.exec("java ArrayTest");
   InputStream is=p.getInputStream(); //从执行ArrayTest类所得来的
   int data;
   while((data=is.read())!=-1)
   {
    System.out.print((char)data);
   }
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }
}

------------->>设计模式<<-------------
1> 在我们进行程序设计时,逐渐形成了一些典型问题和问题解决方案,这就是软件模式。
2> 每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案。
3> 当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式。
<$>单例(Singleton)模式
1> 一个类只有一个实例,而且自行实例化并像整个系统提供这个实例,这个类称为单例类。
2> 单例类的一个重要特点就是类的构造方法是私有的,从而避免了外部用利用构造方法直接创建多个实例。
   如:Runtime类。

单例类的实现:(code)
class Singleton
{
 private static final Singleton st=new Singleton();
 private Singleton()
 {
  
 }
 public static Singleton getInstance()
 {
  return st;
 }
}

posted @ 2006-06-05 14:47 蓝色Saga 阅读(131) | 评论 (0)编辑 收藏

=============================封装类===============
针对八种基本数据类型定义的相应的引用类型-封装类(包装类,包裹类)
基本数据类型          封装类
 boolean               Boolean
 byte                  Byte
 short                 Short
 int                   Integer
 long                  Long
 char                  Character
 float                 Float
 double                Double
所有的封状类都是一个只读类(不能修改的).针对没个基本类型我们只能建立一个这读的。

class Test
{
 public static void main(String[] args)
 {
  int i=3;
  Integer in=new Integer(i);
  int j=in.intValue();
  System.out.println(j);
  String str=in.toString();  //把Integer对象转换为String类型
  System.out.println("str="+str);
  
  String str1="123";
  System.out.println(Integer.valueOf(str1));  //把String类型转换为Integer类型
  
  boolean b1=false;
  Boolean b=new Boolean(b1);
  String s1=b.toString();
  System.out.println(s1);
  
  String s2="NO";
  System.out.println(Boolean.valueOf(s2));
 }
}

*****************Class*********************
1> 在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成
   的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。
2> 获取Class实例的方法有三种:
   <1>利用对象调用getClass()方法获得该对象的Class实例。
   <2>使用Class类的静态方法forName(),用类的名字获取一个Class的是实例。
   <3>运用.class的方式来获取Class实例,对于基本数据类型的封装类,还可以用.TYPE来获取相应的
      基本数据类型的Class实例。
   <4>在运行期间,如果我们要产生某个类的对象,JAVA虚拟机(JVM)会检查该类型的Class对象是否被
      加载,如果没有加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已
      经被加载到内存,就可以用它来产生该类型所有的对象。
   <5>newInstance()调用类中缺省的构造方法。(好处是我们在不知道类的名字的情况下去创造一个实例)
import java.lang.reflect.*;       //子包必须手动导入
class ClassTest
{
 public static void main(String[] args)//throws Exception
 {
  /*
  Point pt=new Point();             
  Class c1=pt.getClass();//利用对象调用getClass()方法获得该对象的Class实例
  System.out.println(c1.getName());
  
  Class c2=Class.forName("Point");//使用Class类的静态方法forName(),用类的名字获取一个Class的是实例
  System.out.println(c2.getName());
  
  Class c3=Point.class;//运用.class的方式来获取Class实例
  System.out.println(c3.getName());
  
  Class c4=Integer.TYPE;//封装类用.TYPE来获取相应的基本数据类型的Class实例。
  System.out.println(c4.getName());
  */
  /*
  System.out.println("before new Point()");
  new Point();
  System.out.println("after new Point()");
  Class.forName("Line");
  */
  /*
  if(args.length!=1)
  {
   return;
  }
  try
  {
   Class c=Class.forName(args[0]);
   Point pt=(Point)c.newInstance();
   pt.output();
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
  */
  if(args.length!=1)
  {
   return;
  }
  try
  {
   Class c=Class.forName(args[0]);
   Constructor[] cons=c.getDeclaredConstructors();
   /*
   for(int i=0;i<cons.length;i++)
   {
    System.out.println(cons[i]);
   }
   Method[] ms=c.getDeclaredMethods();
   for(int i=0;i<ms.length;i++)
   {
    System.out.println(ms[i]);
   }*/
   Class[] params=cons[0].getParameterTypes();
   Object[] paramValues=new Object[params.length];
   for(int i=0;i<params.length;i++)
   {
    if(params[i].isPrimitive())
    {
     paramValues[i]=new Integer(i+3);
    }
   }
   Object o=cons[0].newInstance(paramValues);
   Method[] ms=c.getDeclaredMethods();
   ms[0].invoke(o,null);
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
  
 }
}

class Point
{
 static
 {
  System.out.println("Loading Point");
 }
 int x,y;
 void output()
 {
  System.out.println("x="+x+","+"y="+y);
 }
 Point(int x,int y)
 {
  this.x=x;
  this.y=y;
 }
}

class Line
{
 static
 {
  System.out.println("Loading Line");
 }
}

posted @ 2006-06-05 05:59 蓝色Saga 阅读(54) | 评论 (0)编辑 收藏

~~~~~~~~~~~~~~~~~~~~~~~~~~函数的调用~~~~~~~~~~~~~~~~~~~~
1> 在java中,传参时,都是以传值的形式惊行。
2> 对于基本数据类型,传递的是数据的拷贝,对于引用类型,传递的引用的拷贝。
3> 当我们在打印一个对象的时候,比如System.out.println(pt);,它会自动调用类的toString()方法
   ,所以建议在所有的子类中重写toString()方法。
我们写一个函数用来交换两个变量(x,y)的值.
 code:
class StringTest
{
 public static void change(int x, int y)
 {
  x=x+y;
  y=x-y;
  x=x-y;
 }
 /*
 public static void change(int[] num)
 {
  num[0]=num[0]+num[1];
  num[1]=num[0]-num[1];
  num[0]=num[0]-num[1];
 }
 public static void change(Point pt)
 {
  pt.x=pt.x+pt.y;
  pt.y=pt.x-pt.y;
  pt.x=pt.x-pt.y;
 }
 */
 public static void main(String[] args)
 {
 int x=3;
 int y=4;
 change(3,4);
 System.out.println("x="+x+","+"y="+y);
 }
我们期望的输出结果是 x=4,y=3 然后你运行后发现结果为x=3,y=4,并没有达到我们的要求,为什么呢?那是因为对于基本数据类型,传递的是数据的拷贝,对于引用类型,传递的是引用(首地址)的拷贝。看看下面的内存图解应该你就能看出来了.看看引用类型怎么来实现:


code:
class StringTest
{
 /*
 public static void change(int x, int y)
 {
  x=x+y;
  y=x-y;
  x=x-y;
 }
 */
 public static void change(int[] num)
 {
  num[0]=num[0]+num[1];
  num[1]=num[0]-num[1];
  num[0]=num[0]-num[1];
 }
 public static void change(Point pt)
 {
  pt.x=pt.x+pt.y;
  pt.y=pt.x-pt.y;
  pt.x=pt.x-pt.y;
 }
 public static void main(String[] args)
 {
  /*
   int x=3;
   int y=4;
   change(3,4);
   System.out.println("x="+x+","+"y="+y);
   */
   int[] num=new int[]{3,4};
   change(num);
   System.out.println("x="+num[0]+","+"y="+num[1]);
  
   Point pt=new Point();
   pt.x=3;
   pt.y=4;
   change(pt);
   System.out.println("x="+pt.x+","+"y="+pt.y); 
 }
class Point
{
 int x,y; 
}
再看看引用类型的内存变化图:
以上说明了在Java中函数的调用:
a> 在Java中,传参时,都是以传值的方式进行。
b> 对于基本数据类型,传递的是数据的拷贝,对于引用类型,传递的是引用(首地址)的拷贝。
posted @ 2006-06-05 04:19 蓝色Saga 阅读(36) | 评论 (0)编辑 收藏

^^^^^^^^^^^^^^^对象的克隆^^^^^^^^^^^^^
1> 为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
2> 在派生类中覆盖基类的clone(),并声明为public。
3> 在派生类的clone()方法中,调用super.clone()。
4> 在派生类中实现Cloneable接口。
4> 没有抽象方法的接口叫标识接口。
5> 为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在运行时刻,Object
   的clone()方法能识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原
   始对象的内容一一复制到新的对象空间去。

* 浅克隆是针对没有引用类型的变量来克隆。针对引用类型的克隆应该用Deeply Clone。
浅克隆:
Code:
class FleetClone
{
 public static void main(String[] args)
 {
   Professor p=new Professor("feiyang",23);
   Student s1=new Student("zhangshan",18,p);
   Student s2=(Student)s1.clone();
   s2.p.name="feifei";
   s2.p.age=30;

   System.out.println("name="+s1.p.name+","+"age="+s1.p.age);
 }
}
class Professor
{
 String name;
 int age;
 Professor(String name,int age)
 {
  this.name=name;
  this.age=age;
 }
}

class Student implements Cloneable
{
 Professor p;
 String name;
 int age;
 Student(String name, int age,Professor p)
 {
  this.name=name;
  this.age=age;
  this.p=p;
 }
 public Object clone()
 {
  Object o=null;
  try
  {
   o=super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   e.printStackTrace();
  }
  return o;
 }
}
改变学生s2的教授信息,打印s1教授信息,结果为:name=feifei,age=30.产生这个结果是因为String是一个常量类型.
 
深克隆
code:
class DeeplyClone
{
 public static void main(String[] args)
 {
   Professor p=new Professor("feiyang",23);
   Student s1=new Student("zhangshan",18,p);
   Student s2=(Student)s1.clone();
   s2.p.name="Bill.Gates";
   s2.p.age=30;
   System.out.println("name="+s1.p.name+","+"age="+s1.p.age);
 }
}
class Professor implements Cloneable
{
 String name;
 int age;
 Professor(String name,int age)
 {
  this.name=name;
  this.age=age;
 }
 public Object clone()
 {
  Object o=null;
  try
  {
   o=super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   e.printStackTrace();
  }
  return o;
 }
}

class Student implements Cloneable
{
 Professor p;
 String name;
 int age;
 Student(String name, int age,Professor p)
 {
  this.name=name;
  this.age=age;
  this.p=p;
 }
 public Object clone()
 {
  //Object o=null;
  Student o=null;
  try
  {
   o=(Student)super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   e.printStackTrace();
  }
  o.p=(Professor)p.clone();
  return o;
 }
}
打印结果为:name=Bill.Gates,age=30,这就是深克隆.
posted @ 2006-06-05 04:15 蓝色Saga 阅读(54) | 评论 (0)编辑 收藏

     人生在世,最要紧的不是我们所处的位置,而是我们活动的方向.何时,何地一何种方式开始我们的一生,是无法选择的.我们一生下来就处于一种身不由己的环境中.但随着年龄增长,我们的选择就越多.我们可以选择居处,婚姻,朋友,可以选择人生方向.做出越多的人生选择,就越应该为在的处境负责任.
    有了目标,内心的力量才能找到方向.满腔的热血,能量才有着落,才有责任,使命,荣誉,甚至"健康"......
posted @ 2006-06-05 04:11 蓝色Saga 阅读(61) | 评论 (0)编辑 收藏