Java知识点总结

1、==与equals

java的数据类型分为基本数据类型和复合数据类型;

基本数据类型(四类八种):整形:byte,short,int,long;浮点型:float,double;字符型:char;逻辑型:boolean;

在内存中直接存放于栈中,基本数据类型之间的比较用==比较,比较的是他们的值

复合数据类型:常指的是类,在内存中对象存在于堆中,对象引用则存在于栈中

==进行比较的时候,比较的是引用,即对象在内存中的地址;所以,同一个对象比较时,因内存地址相同,故返回true,不同对象比较时,因地址不同,故返回false;

equals进行比较的时候,需了解equals有没有被覆写,在java中,所有的类都继承于基类Object,在Object类中,equals方法是用==比较的,源码如下所示:

1 public boolean equals(Object obj) {

2 return (this == obj);

3 } 

所以,在默认情况下,equals同==一样,比较的对象的内存地址;

但是,一些类覆写equals方法,比如String,Integer等,它们有自己的实现,如下String类中equals方法的实现所示:第一个同==一样,判断内存地址是否一样,即判断是否为同一个对象,如果是同一个对象则返回true,否则继续往下走,执行第二个if,第二个if的条件为参数是否为String的实例,如果是的的话,判断两个对象的字符序列是否相等;相等返回true,不相等返回false;

 1 public boolean equals(Object anObject) {
 2         if (this == anObject) {
 3             return true;
 4         }
 5         if (anObject instanceof String) {
 6             String anotherString = (String) anObject;
 7             int n = value.length;
 8             if (n == anotherString.value.length) {
 9                 char v1[] = value;
10                 char v2[] = anotherString.value;
11                 int i = 0;
12                 while (n-- != 0) {
13                     if (v1[i] != v2[i])
14                             return false;
15                     i++;
16                 }
17                 return true;
18             }
19         }
20         return false;
21     }

举例说明:

 1 class A{
 2     
 3 }
 4 public class Test {
 5     
 6     
 7     public static void main(String[] args) {
 8         //比较普通类,没有复写了equals方法;
 9         A a = new A();
10         A b = new A();
11         System.out.println("use ==");
12         System.out.println( a == b); //==比较
13         System.out.println("use equals ");
14         System.out.println(a.equals(b));//equals比较
15         System.out.println();
16         //String类,复写了equals方法;
17         String s1 = "abc";
18         String s2 = "abc";
19         String s3 = s1;
20         String s4 = new String("abc");
21         String s5 = new String("abc");
22         //s1 and s2 use ==
23         System.out.println("s1 and s2 use ==");
24         System.out.println(s1==s2);
25         System.out.println();
26         //s1 and s2 use equals
27         System.out.println("s1 and s2 use equals ");
28         System.out.println(s1.equals(s2));
29         System.out.println();
30         //s1 and s3 use ==
31         System.out.println("s1 and s3 use ==");
32         System.out.println(s3 == s1);
33         System.out.println();
34         //s1 and s3 use equals
35         System.out.println("s1 and s3 use equals ");
36         System.out.println(s1.equals(s3));
37         System.out.println();
38         //s4 and s5 use ==
39         System.out.println("s4 and s5 use ==");
40         System.out.println(s4 == s5);
41         System.out.println();
42         //s4 and s5 use equals
43         System.out.println("s4 and s5 use equals ");
44         System.out.println(s4.equals(s5));
45         System.out.println();
46         //s1 and s4 use ==
47         System.out.println("s1 and s4 use ==");
48         System.out.println(s1 == s4);
49         System.out.println();
50         //s1 and s4 use equals
51         System.out.println("s1 and s4 use equals ");
52         System.out.println(s1.equals(s4));        
53     }
54 }

运行结果:

use ==
false
use equals
false
----普通类A继承了Object类,但没有复写equals方法,故==和equals都是比较的内存地址,a和引用了两个对象,所有返回的都是false
s1 and s2 use ==
true

s1 and s2 use equals
true
----s1和s2指向同一个对象“abc”;故都返回true;


s1 and s3 use ==
true

s1 and s3 use equals
true
----s3=s1,意味着将s1的值复制了一份,赋给了s3,s1指向的是对象“abc",所以s3也指向对象”abc“,故都返回true;


s4 and s5 use ==
false

s4 and s5 use equals
true
----s4和s5指向的是由new创建的两个String对象,故==返回的是false;由上面的源码可知,String复写了equals方法,两个对象的字符序列是相同的,故equals返回的是true;


s1 and s4 use ==
false

s1 and s4 use equals
true

----与s4和s5一样,不再赘述;

2、静态变量与实例变量的区别

 java的成员变量有两种,一种是被关键字static修饰的变量,称之为静态变量或者类变量,另外一种是没有被static修饰的变量,称为实例变量

实例变量属于对象级别,只有创建了实例对象,变量才会在内存中分配空间,才能使用这个实例变量;

静态变量属于类级别,只要程序加载了类,静态变量就会在内存中分配空间,就可以使用静态变量,静态变量存储在java方法区中

 

3、java程序在内存中的存储分配情况

java程序在内存中的存储分配情况:

堆区:
1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身


栈区:
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。


方法区:
1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

 

4、final关键字

使用final关键修饰一个引用类型的变量时,引用变量时不能改变的,但是引用变量所指向的对象的内容是可以改变的,举例说明:

final StringBuffer ss = new StringBuffer("sssss");

ss = new StringBuffer("aaa"); //该语句编译错误

ss.append("aaaa");
System.out.println(ss);  //这两句编译正确,且最终显示sssssaaaa


5、String ,StringBuffer,StringBuilder

都是属于java.lang包;

都使用字符数组保存字符串,

不同的是:String是不可变的,StringBuffer和StringBuilder是可变的;

查看源码可知:

String类中保存字符串的数组有final修饰付修饰,故是不可变的且String类中没有append()方法;

 private final char value[];

而StringBuffer,StringBuilder 均继承自抽象类AbstractStringBuilder,该抽象类中保存字符串的数组没有被final修饰符修饰,故是可变的,且这两个类都有append方法;

 char[] value;

StringBuffer,StringBuilder的不同之处在于:StringBuffer是线程安全的,StringBuffer类中的方法加了同步锁,故是线程安全的;StringBuilder类中的方法没有,故是非线程安全的;

6、面向对象的特征

面向对象的变成语言有4个特征:封装,抽象,继承,多态


 


 

posted @ 2016-09-09 08:51  喵呜1314  阅读(474)  评论(0编辑  收藏  举报