java笔记

不断找漏洞。自我总结


1.

A a=new A(1);
	A b=new A(2); 
	b=a;
	System.out.println(b.a);  //  1
	b.setA(0);
	System.out.println(a.a); //0
   注意:  b=a; 实际上意思是变量a,b指向同一个内存地址。这是因为,对于 引用类型的变量值是所指对象的内存地址。b=a,就是将a的地址赋值给a,因此a,b指向同一块内存空间。再深究到JVM的垃圾回收机制的话,此时
A b=new A(2); 
对象的内存将被释放。


2.  

 if (num < 0 && num == Math.abs(num)) 
		    	  int a=5;

 这样写是错误的。因为if语句后面的语句如果不加{ },必须是可执行语句。赋值语句不可以的!


3. 更新于2011.8.12  23:36

唉。又忘记了  == 和 equal 的区别了。。  == 是比较的内存地址,equal才是比较的值。对于引用型变量,如果是比较值的话,最好的办法是重写equal方法。

Integer a=new Integer(5);
		Integer b=new Integer(5);
		System.out.println(a==b);
这个打印出来false。因为new一次就申请一个内存空间。

Integer a=2;
		Integer b=2;
		System.out.println(a==b);      //打印出来true,因为指向同一个内存空间。 a,b都是指向一个常量2。(2存在于栈中!)
		//同理:
		String s1="a";
		String s2="a";
		System.out.println(s1==s2);     //打印true 因为指向同一个内存空间。(牵扯到常量池)
        System.out.println(s1=="a");     //打印true 因为都是指向一个常量的。 
		
		String s11=new String("a");
		String s21=new String("a");
		System.out.println(s11=="a");     //打印false。s11是新申请的内存。"a"是存在于常量池中的。
		System.out.println(s11==s21);     //打印 false  因为两边都是通过new新申请内存空间,

  要注意:int a=3,这个3是存在于栈中的

 而String str="a";这个a存在于常量池的。

 八种基本数据类型,及对象引用的空间,均是分布在栈中,因为它们的大小,在分配空间前就能确定。
常量池是用来存字符串常量的。不存整型变量。

4.更新于2011 .8.12  2:05

为什么要使用ArrayList里面的 toArray()方法。看下面代码就知道了:

		List<String> list=new ArrayList<String>();
		list.add("a");
		System.out.println(list.size());    //输出1
		List<String> l1=list;
		l1.remove(0);
		System.out.println(list.size());  //输出0
		System.out.println(l1.size());    //输出0

可以看出来如果直接通过赋值语句传递List类型变量的话,更改一个List会对别的List产生一样的后果。这通常不是我们希望看到的。即使将上面的代码改为下面,也依然得到相同的结果!

List<String> l1=new ArrayList<String>();
l1=list;


至于原因,稍微延伸一下。假设有一个Student类,我们都知道如果

Student student1=new Student(3,"zhangsan");
Student student2=s1;
那么,s1和s2将同时指向同一个内存地址。说得更详细点是student1,student2变量中存储的东西是一样的,这个东西就是一个Student对象的地址。此时,如果我们让对象s2调用类Student里set()方法改变s2里面的一些属性,同时也会更改对象s1里面的属性。

ArrayList也是一个类。和Student没啥大的区别,唯一的区别就是ArrayList是已经写好包装好的类,本质上两者还是一样的。这样的话,就不难解释为什么出现上面的情况。

这就是我们需要用到  toArray()方法的原因。对于这个方法,API是这样解释的:

按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。

由于此列表不维护对返回数组的任何引用,,因而它将是“安全的”。(换句话说,此方法必须分配一个新的数组)。因此,调用者可以自由地修改返回的数组。


但是在用到toArray()方法的时候需要注意:它的返回值是一个Object型的数组。如果还想继续得到String类型的数组,需要这样做:

String []s=list.toArray(new String[0]);

刚才从ArrayList延伸到了普通的类,我们都知道如果想把上面提到的student2=student1,改变一下,使student2既得到student1的属性,又可以自由改变这些属性而不影响到student1。恩,那就是clone()方法。要想使用clone( )方法,必须实现Cloneable接口。在这里就不多说了。

还是回到ArrayList上面来,我们利用toArray()的原因是向得到一个与原来数组相同的数组,但是又想新开辟内存地址,想与原来的数组划清界线。这不就是类Object里面clone()方法的功能吗?本来还担心,使用clone()方法得实现Cloneable接口,那不就是得重写ArrayList吗?好麻烦。。。不过后来竟然在API中看到ArrayList中自带了clone()方法。。欣喜啊~这样的话,我们其实就可以抛弃toArray()方法了。两者实现的是相同的功能,但是clone()方法返回的是ArrayList,而toArray()得到的只能是普通数组。。ArrayList当然比普通数组强大得多了。

总结一下:这次从 toArray()方法出发,到最后把它给抛弃了。。(或许还有别的好处,望赐教。。)

5.  2011.8.12 晚 10:10

数组为 Null和数组大小为0,是两个不通的概念。

List<String > l=new ArrayList<String>();
		System.out.println(l==null);   //false
		System.out.println(l.size());  //输出0

6.  2011.9.5 16:04

 6.1  

(int)Math.random()*10;
这个句子的执行顺序是:先(int)Math.random(),再乘以10

 6.2

  final标识符的意思是不能被改变。

 1.类被final修饰的话,表示这个类不能被继承。

    final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许    改变,并且确信这个类不会载被扩展,那么就设计为final类。

 2.方法被final修饰的话,表示这个方法不能被改变,即不能被子类里面的方法覆盖(可以被继承)。

   使用final方法的原因有二: 
  第一、把方法锁定,防止任何继承类修改它的意义和实现。 
  第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。

  3.变量被final修饰的话,表示变量的值不能被改变。并且在对象生成的时候必须有值。这就决定了final变量的两种赋       值方式:

     方式一:定义变量的时候进行赋值

    

 final static int a=4;



     或者,也可以用函数对变量进行赋值:


final static int a=(int)(Math.random()*10);


    

    方式二:在构造函数里面对变量进行赋值:

       

final  int a;
	public MainClass(int b) {
	a=b;
	}
   这两个地方只能选其一,要么在定义时给值,要么在构造函数中给值,不能同时既在定义时给了值,又在构造函数中给另外的值。

  6.3 重载是载同一个类里面写另外一个方法和已经存在的某个方法同名,但是参数不一样。

     重写是对于继承而言的,继承类重新编写基类的方法。

  6.3 

for(int i=2,double j=5;i<=6;){
				
			}
  这样写实错误的。

   

for(int i=2,int j=5;i<=6;){
				
			}
这样写也是不对的。

for(int i=2, j=5;i<=6;){
				
			}
 而只有这样是对的!


7. 2011.9.6 15:40

 泛型:

  

package com.bjsxt.dp.strategy;

public abstract class Compartor <E>{
	public abstract int compare(E t1,E t2);
}

package com.bjsxt.dp.strategy;

public class ComparatorCatWeight extends Compartor<Cat> {

	@Override
	public int compare(Cat t1, Cat t2) {
		if (t1.getWeight() > t2.getWeight())
			return 1;
		else if (t1.getWeight() < t2.getWeight())
			return -1;
		else
			return 0;
	}

}


8. 2011.11.23 11:25

也许你还记得,Function 对象这一章中介绍过 Function 的 toString() 方法通常输出的是函数的源代码。覆盖该方法,可以返回另一个字符串(在这个例子中,可以返回 "Function code hidden")。不过,toString() 指向的原始函数怎么了呢?它将被无用存储单元回收程序回收,因为它被完全废弃了。没有能够恢复原始函数的方法,所以在覆盖原始方法前,比较安全的做法是存储它的指针,以便以后的使用。有时你甚至可能在新方法中调用原始方法:

Function.prototype.originalToString = Function.prototype.toString;

Function.prototype.toString = function() {
  if (this.originalToString().length > 100) {
    return "Function too long to display.";
  } else {
    return this.originalToString();
  }
};

TIY

在这段代码中,第一行代码把对当前 toString() 方法的引用保存在属性 originalToString 中。然后用定制的方法覆盖了 toString() 方法。新方法将检查该函数源代码的长度是否大于 100。如果是,就返回错误信息,说明该函数代码太长,否则调用 originalToString() 方法,返回函数的源代码。

 

这个表明,在js里面,将函数看成一个变量会容易理解一点。


9. 2011.11.23 19:32

 

在JavaScript里面:

     var  arr = new Array()
	arr[0]="1";arr[2]="1";arr[2]="1";
 	for(var  t   in  arr){
		document.write(t)
		}	

输出的是  0 1 2

        这点是不同于Java的。

   

10 2011 .11.25  21::45

   在jsp页面中,可以单独定义一个方法,而不是必须在类里面,则必须定义在<% !     %>  里面

11  2012.3.20 18:14

     HashMap 与HashTable的最大区别是HashMap的键可以为null,为HashTable的不可以。


12. 2012.9.14
(Element)node1.getFirstChild()应该是从右至左运算,即先运算node1.getFirstChild(),然后再强制转换。 .比()运算优先级高。


12. 2012.12.14 20:11
    在编程的时候,特别是在看别人做好的项目的时候,不可因为一个地方有疑问而据纠结很长时间,而是应该抓住重点!!
 
 
13.2012.12.22 15:55
在Action中得到tomcat的绝对路径。
String realPath = request.getSession().getServletContext().getRealPath("/")+"WEB-INF/image/";
 
 


  

你可能感兴趣的:(java,list,function,String,HashMap,Integer)