学习亦游戏

学习JAVA就像玩WOW,学好基础知识就像把号练到满级,做小程序就像单刷小副本,做大项目就像下团队副本,开新项目就像团队开荒,从五人到十人到二十五人,游戏难度随着我们的强力而增强,这亦是学习的乐趣吧!...

JAVA学习笔记

第三章 面向对象

 

1. 类的成员变量会默认初始化,而局部变量不能,必须先赋值再使用。所有的引用类型(除了八种基本类型之外的变量类型),默认null。基本类型只占用一块内存;引用类型占用两块(名字,实体)。引用即为C/C++中的指针

 

2. 类是静态的概念,存放在code seg;对象需分配的内存大小只有在运行期间(javac是编译期间,java是运行期间)才能知道,new出的东西放在堆内存里。堆内存区比较大,动态分配内存。如果对象不再使用,由垃圾回收系统回收内存。类的成员变量(除了静态变量)在不同的对象中有不同值,方法只有一份(代码区中),执行的时候才占用内存

 

3. 函数调用中传递参数时,基本类型传递数据值本身,引用类型传递对象的引用

 

4. codedatastackheap 局部变量分布在stack seg字符串常量data seg

 

5. this一般出现在方法的定义中,代表使用该方法的对象的引用;也可以用于处理方法中成员变量与参数重名的情况

 

6. static变量是静态的变量,存放在dataseg 。字符串常量分配在 data segment。用static声明的方法是静态方法,在调用该方法时,不会将对象的引用传递给它,所以static方法中不能访问非static的成员,因为非静态成员专属于一个实例化对象,必须new一个对象才能够使用。

 

7. 解决类的命名冲突问题,引入包(package)机制,提供类的多重类命名空间。约定俗成的包名:公司的域名颠倒过来—com.bjsxt.java140. package语句是java源文件的第一条语句,指明该文件中定义的类所在的包(若缺省该语句,则指定为无名包)

         如果要把类放入包中,第一句话要写package,包层数随意,编译出来的class文件,必须位于正确的目录里面(和包的层次要完全一致),该类的源代码可能会产生影响,最好删除或者转移到别的目录中。

         如果想要在另外一个类中用包中的类,必须在文件的开头用import引入类全名,当然,同一个包中的类不需要import

         Class文件的最上层包所在的目录(或者是打到jar包中,jar包所在的目录)必须在classpath中,(例如:com.sxt.abc.classabc.class最上层的包是comcom位于 d:\java,那么d:\java必须在classpath中)才能保证其他类能找到它。

命令行中执行一个类,需要写全包名。如果两个项目都设了classpath,但是又有重名的类,会很麻烦,分不清哪个类,要注意classpath中的先后顺序Eclipse中不存在这个问题。每一个自己的project应该有自己专门的classpath,跟其他的classpath不共享。

 

8. j2sdk 中主要的包

Java.lang 包含java语言的核心类,StringMathIntegerSystemThread。这个包中的类不需要import,直接能用

Java.awt

Java.applet现在已经不怎么流行了

Java.net包装了TCP,UDP网络上的应用程序

Java.io输入输出流

Java.util实用工具类,如定义系统特性、使用与日期日历相关的函数

        

         可以将类打成jar包,供他人使用, 首先将命令行路径,定位到最上层的包的上一层,然后输入打包语句“jar –cvf xx.jar *.*”,jar包生成目录与最上层包同级

         可以将jar的路径设为classpath

 

9. java只支持单继承,c++支持多重继承

         Java权限修饰符一方面可以修饰成员变量或者成员方法,另一方面可以修饰classDefault修饰,包外的都无法访问,子类也不能。Protected是为了让包外的子类访问。

Private类型的属性,子类无法直接使用,只能通过调用父类方法使用。父类引用指向子类对象,该引用也无法调用父类的private属性。

对于class,只能用public(谁都可以访问)default修饰(同一个包中其他类能访问)

所有的关键字,都可以修饰内部类

 

10. 重载overload):在同一个类中,方法同名,同返回值,参数不同(类型不同or个数不同)

         重写overwrite/override):子类中根据需要对从基类中继承来的方法进行重写(将会覆盖掉基类方法),方法同名,同返回值,同参数列表。不能使用比被重写的方法更严格的访问权限。如果要重写一个方法,最好去复制原方法的声明,以免出错。

 

11. super是当前对象中的父类对象的引用,this指向当前对象的引用

 

12. 子类的构造过程中,必须调用基类的构造方法。子类在自己的构造方法中,使用superargument_list)调用基类的构造方法,使用thisargument_list)调用本类的其他构造方法。如果调用super,必须写在子类构造方法的第一行。

         子类的构造方法中,如果没有显示的调用基类构造方法或者自身的构造方法,则系统默认调用基类的无参构造方法,而如果基类中又没有无参构造方法,则编译出错。

 

13. 一个字符串和另外一种类型做连接操作时候,例如:” ” + int/对象,另外一种类型自动调用该对象类的toString() 方法,转换成String类型,再做连接。

 

14. hashcode 哈希编码 独一无二的代表一个对象,通过他可以找到这个对象所在的位置。

 

15. 默认的equals方法,与==意义相同,都是比较是否指向同一个对象。所以,如果需要比较不同对象之间具体内容的不同,需要重写。

         关键词instanceof是用来判断一个对象实例是否是另外一个类或接口的实现,或者是否是其子类子接口的实现ooinstanceof TypeName 第一个参数是对象实例名,第二个参数是具体的类名或接口名

       如果需要的参数,是一个父类对象的引用,可以传入子类对象,父类引用指向子类对象,称为向上转型(upcasting),但是父类的引用不能访问子类对象新增的成员(成员和方法),实质上就是:这个引用只能看到子类对象中包含的父类对象。反之称为向下转型(downcasting),又称为强制转换。这种父类引用,可以强制类型转换为子类对象,因为它实际上就是指向的子类对象,不能强制转换成其他的类型。

 

16. 程序的可扩展性

       1)单独定义好多个方法,最原始的途径,无扩展性可言

       2)在一个方法的参数中,定义父类的引用,在实际用的时候传入子类对象,在方法中判断此对象属于哪个子类,然后再去执行其中的方法,或者调用其中的成员变量。程序的可扩展性比单独定义好多个方法强

       3)多态,不需要判断传入子对象的类型,自动动态绑定所需要的方法,可扩展性达到了最好

 

17. 动态绑定 Dynamicbinding多态 Polymorphic Polymorphism多态性,迟绑定Late binding)重点在于对内存图的理解

       在执行期间(而非编译期间)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法(方法都存放在 code seg,在执行期间使用)

       深层机制:在实际当中找方法的时候,在对象内部有一个方法的指针指向该方法,但是在new这个对象的时候,指针会根据新new的对象的不同而改变,指向新对象重写的方法,所以叫动态绑定(只有在运行期间,new出对象来,才能确定到底调用的是哪个方法,实际当中的地址,才会相应绑定到这个方法的地址上)。只要方法重写了,就会使用这种机制

       表面现象:对象作为父类身份传入参数,但是执行的却是自己重写的方法。

       Main函数中都是业务逻辑,表示功能的变化,相当于大管家,功能改变则必须变。业务方法,将结构设计好定义好,不需要变,如果以后想添加新的东西,继承父类,重写它的方法,搞定

       多态的存在,有三个必要条件:

       1)要有继承 2)要有重写 3)父类引用指向子类对象

       一旦满足,当调用父类当中被重写的方法时候,实际当中new的是哪个子类对象,就调用哪个子类对象重写的方法

 

18. abstract修饰抽象类,抽象方法。

       含有抽象方法的类(只有一个也算),必须声明为抽象类,抽象类必须被继承才能使用,所有的抽象方法必须全部被重写。

       抽象类不能被实例化。

       抽象方法只需声明,不需实现。

       配合多态,将那些总被重写,没必要实现的方法,写成抽象类,只有方法的声明,没有{类体},任何人不能修改类体。相当于C++中的虚函数,纯虚函数

       对于父类是抽象类型的子类,如果子类觉得自身不易实现父类的抽象方法,可以将自己也声明为抽象类,将方法还声明为抽象方法,让下一级子类去实现。实质是:抽象类被抽象类继承

       必须把父类中的所有抽象方法都实现么 必须全部重写!即便有些用不到。

       抽象类中,可以有非抽象方法么? 可以

 

19. final 可以用来修饰 —— 类(不能被继承)、方法(不能被重写)、变量(不能改变值)(成员变量,局部变量(形参)),相当于C++const关键字。

       使用final修饰的类有很多,不能被继承,更不能重写:java.lang.Stringjava.lang.Mathjava.lang.Boolean …

 

20. java只支持单继承,但是现实中存在着很多多继承的东西,用接口实现。使用implements关键词

       接口(interface)是抽象方法和常量值的定义的集合。本质上,接口是一种特殊的抽象类。定义一个接口时,interface替代class的位置。接口特征:

       1所有的方法全部默认public abstract的,没有{类体},也只能是public static的,却不用abstract关键字,public也可以省略。

       2所有的成员变量(不包括方法),即所有声明的属性,都默认public static final的,写不写作用一样,也只能是public static final的。

       3)只包含常量和方法的定义,没有变量和方法的实现

       4)接口可以多重实现,一个类可以实现多个接口,即类可以实现多继承

       5)接口可以继承其他的接口,并添加新的属性和抽象方法

       接口属性(成员变量)一定要定义成 public static final的原因:为了修正C++中多继承时容易出现问题的地方,多继承的多个父类之间,如果它们有相同的成员变量的时候,引用十分麻烦,而且运行时候会出现各种问题。接口的成员变量是static final的,只属于接口本身。

       1)多个无关的类,可以实现同一个接口

       2)一个类可以实现多个无关的接口

       3)与继承关系类似,接口与实现类之间存在多态性

       4)接口中的抽象方法,子类必须全部重写,除非子类也是抽象类

每一个接口暴露出实现这个接口的对象的一部分方法,与其他接口无关。对于多继承的对象,所继承的接口切换使用时,只需将对象强制转换成要使用的接口类型。

 

21. 同名的方法,仅仅是返回值不同,因为返回值可以不用,所以难以区分这两个方法。如果两个接口都含有同名的方法,仅仅是返回值不同,它们同时被一个类实现的时候,就会发生混乱,暂时无法解决!这种现象很少碰到。

 

22. 约定俗称的命名规则:

       1)类名的首字母大写

       2)变量名和方法名的首字母小写

       3)运用驼峰标识

 

第四章 异常处理

 

23. 异常:运行期出现的错误(除0溢出,数组下标越界,所要读取的文件不存在),观察错误的名字和行号最重要

       出现异常之后,java自动生成一个异常类对象(封装了异常事件的信息),并被提交给java运行时系统,这个过程称为抛出异常(throw);java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获异常(catch)。

       Error是不可以处理的异常(动态连接失败、虚拟机错误等),Exception是可以处理的,RuntimeException是可以处理也可以不处理的

       Exception结构下:有些方法后直接用 throws注明可能出现的异常,实际当中用throw抛出,这类exception必须catch RuntimeException是经常出现的错误,系统自动检测并将它们交给缺省的异常处理程序(用户可不必对其处理)。

       getMessage()方法,用来得到有关异常事件的信息。

       PrintStackTrace()方法,用来跟踪异常事件发生时执行堆栈的内容

 

24. finally语句

       为异常处理提供一个统一的出口,使得在控制流程转到程序的其他部分之前,能够对程序的状态做统一的管理。无论try所指定的程序块中是否抛出例外,finally所指定的代码都要被执行。通常在finally语句中可以进行资源的清除工作(关闭打开的文件,删除临时文件)。

       调用有异常抛出的方法时候,应该try catch这种异常,如果处理不了,可以抛出,交给上一级调用者去处理。在main方法后写 throws Exception很省事,但这是不好的编程习惯,应该将异常try catch,这是程序员应该做的事情。

       还有一种方式,手动处理,先用throws声明可能出现的异常,再用throw关键词:throw new Exception(“….”);

       如果需要处理多个异常,先逮小的,再逮大的。

       要重写的方法抛出异常,那么重写的方法也必须抛出一样的异常,或者不抛异常。

 

第五章 数组

 

25. C/C++中的数组可以分配在栈空间上,但是java不能,因为java的数组是引用类型的。Java声明数组不能指定其长度,如:int a[5]; 这是错误的!正确格式为:int []a =new int[5]; java中所有new出来的东西都是分配在堆内存上。

       对于引用类型的数组,堆空间中存放的是指向数组的引用。内存图如下:

 

26. 动态初始化:数组先定义,再为数组元素分配空间和赋值。

       静态初始化:数组定义的同时,维数组元素分配空间并赋值。Int a[] = {1,2,3};

       数组分配空间后,每个元素按照成员变量的规则被隐式初始化。Boolean默认为false

 

27. main函数中数组参数(String [] args 使用命令行参数。在运行时,使用命令

java className参数1 参数2 参数n

       System.exit(-1);系统退出,当前虚拟机退出。-1表示非正常退出,0表示正常退出。在windows中看不出区别,-10都行

       dos环境下,乘号*有特殊含义,用字母x代替

       将字符串String类型转换成其他类型,例如:Double.parseDouble(stringName);

 

28. 选择排序算法(从上往下,从左往右比较)第一位与后面每一个比较,每次都使最小的置顶,第一位向后推进

       public static void selectSort(int [] a){

              int k,temp; //临时变量重复使用,算法加速

              for(int i = 0 ; i< a.length;i++){

                     k = i;

                     for(int j = k+1;j<a.length; j++){

                            if(a[k] > a[j]) k= j; //每次对比,一比到底,省去无意义的调换

                     }

                     if(k != i){

                            temp = a[i];

                            a[i] = a[k];

                            a[k] = temp;

                     }

              }

       }

 

29. year>date.year? 1 : (year < date.year ? -1 :( month > date.month ? -1 : (month <date.month ? -1 :(day > date.day ? 1 : (day < date.day ? -1 : 0))))); 这种写法执行速度快,但是程序可读性差。

       冒泡排序法:每次都从第一位向后滚动比较,每次使最大的沉底,最小的上升一次,最后一位向前推进

       public static void bubbleSort( Date[] days){

              int len = days.length;

              Date temp;

              for( int i = len-1 ; i >= 1 ;i--){

                     for(int j = 0; j < i;j++){

                            if(days[j].compare(days[j+1])> 0){

                                   temp =days[j+1];

                                   days[j+1] =days[j];

                                   days[j] =temp;

                            }

                     }

              }

       }

 

30. 作业:1. 用冒泡排序法 date类进行排序 2. 用冒泡排序法 int类型数组排序 3. 使用选择排序法 date类型数组排序 4. Count3Quit算法

 

31. 搜索算法

       一般先排序,如果无序,只能挨个搜索,效率极低。所以搜索之前先排序

       二分法搜索算法(折半查找):

       public static int binarySearch(int[]a ,int num){

       if (a.length == 0) {

           return-1;

       }

       intstartPosition = 0;

       int endPosition= a.length - 1;

       int midPosition= (startPosition + endPosition)/2;

       while(startPosition <= endPosition) {

           if(a[midPosition] == num) {

              returnmidPosition;

           }

           if(a[midPosition] > num ) {

              endPosition = midPosition - 1;

           }

           if(a[midPosition] < num ) {

              startPosition = midPosition + 1 ;

           }

           midPosition = (startPosition +endPosition)/2;

       }

       return-1;

    }

 

32. 二维数组(数组的数组)

     随着维数的增加,内存图像树状图一样延伸(而不是维度扩展)。

    数组的初始化:

数组的拷贝:使用java.lang.System类的静态方法

public static void arraycopy(Object src,int srcPos,Objectdest,

int destPos,int length)

    数组下标越界会抛出异常 IndexOutOfBoundsException

 

第六章 常用类

 

33. 对于String,只有new出来的才是对象,直接赋值的是字符串(存储于data seg)。String类已经重写了equals方法(比较对象内容)。

    String是不可变的字符序列;StringBuffer是可变的字符序列

    StringBuffer类中的 public StringBuffer replace(int start,

                            int end(不包括end所在的位置),

                            String str)

 

34. 包装类 封装了一个相应的基本数据类型数值,并为其提供了一系列操作

    long类型的数转换成Long类型对象:new Longlong value

    Long类型对象转换成long类型数:longValue(),intValue()

    String类型转换为int类型,Integer.parseInt(string);

 

35. Math 各种运算

    java.io.File    代表系统文件名(路径和文件名)

    路径符号:String directory = “dir1” + File.separator + “dir2”;

                            =“dir1/dir2”        = “dir1\\dir2”

    三种都可以,但是第三种只能在windows环境下使用,反斜杠’\’java中是转义字符,必须用’\\’才能表示路径分隔符,前两种在linux下也能使用

    如果class文件在包中,包名+文件名会被系统认为是文件名,所以路径是最上层包所在的路径。

 

36. java.lang.Enum类型 java1.5才有这种类型)使用enum关键字

    定义:public enum classname {red ,green, blue};

    使用:classname cn = classname.red;

 

第七章 容器(1136:一个图; 一个类Collections 三个知识点:增强forGeneticsAuto-boxing/unboxing;六个接口)

 

37. 一个图

Collection添加对象都是一个一个添加,其中,Set没有顺序不可重复,List有顺序可重复(两个对象互相equals);

Map都是成对添加。Map接口定义了存储“键(key)—值(value)映射对”的方法。

 

38. 比较对象是否相等,一般涉及到equals方法;equalshashCode方法必须同时重写。当对象用在Map接口中作为key(字典索引),涉及到hashCode方法,因为效率会更高。

 

39. 所有实现了Collection接口的容器类,都有一个iterator方法(Map没有),用于返回一个实现了Iterator接口的对象(父类引用指向子类对象)。

    使用Iterator遍历的时候,会将当前对象锁定,只有自己能使用,所以只能使用Iteratorremove方法处理当前对象,不能使用Collectionremove方法。

 

34. 增强型for循环:除了简单遍历并读出其中内容外,不建议使用。

    数组:不能方便的访问下标值。

    集合:与使用Iterator相比,不能方便的删除集合中的内容。(在内部也是调用Iterator

 

35. Set接口Collection的子接口,没有提供额外的方法,但实现Set接口的容器类中,元素无顺序不重复。J2SDK API 中提供的Set容器类有HashSetTreeSet

    List接口Collection的子接口,实现List接口的容器类中,元素有顺序可以重复。J2SKD 所提供的List容器类有 ArrayListLinkedList 等。

 

36. java.util.Collections ,提供了一些静态方法,实现了基于List容器的一些常用算法。

    所有可以“排序”的类,都实现了java.lang.Comparable接口Comparable接口中只有一个方法,public int compareTo(object obj);

    1. 返回0:相等;2. 返回正数:大于; 3. 返回负数:小于

 

37. Array读快改慢;Linked改快读慢;Hash两者之间。

    HashTableVector已经逐渐淘汰,因为它们内部是锁定的,读写效率都极低。

 

38. 实现Map接口的类,用来存储“键-值”对(名值对),通过键来标识,所以键值不能重复,通过查询hashcode来区分。Map接口的实现类有HashMapTreeMap(用二叉树实现)等。

 

39. JDK1.5之后。Auto-boxing/unboxing 在合适的时机自动打包、解包  自动将基础类型转换为对象;自动将对象转换为基础类型。

 

40. 泛型 Generics java泛型的底层与C++不太一样

    起因:JDK1.4以前类型不明确:装入集合的类型都被当做Object对待,从而失去自己的实际类型;从集合中取出时往往需要强制类型转换,效率低,容易产生错误。

    方案:在定义集合的时候,同时定义集合中对象的类型。

    好处:增强程序的可读性和稳定性。

    泛型与自动打包功能结合使用,程序更加简化。凡是用到集合的地方,尽量使用泛型。

可以在定义Collection的时候指定,也可以在循环时用Iterator指定,建议都指定。

 

第八章 IO

 

41. J2SDK 提供的所有流类型,位于包java.io内,都分别继承自以下四种抽象流类型

“读入写出”

字节流byte

字符流 两个字节

输入流

InputStream从文件进入程序

Reader从文件读出进入程序

输出流

OutputStream输出程序进入文件

Writer从程序写入文件

 

42. 问题:使用FileReader,汉字依然出现乱码

    BufferInputStreammark方法。

 

43.

缓冲流 Buffer

    转换流 InputStreamReader(将InputStream转换为Reader)和 OutputStreamWriter (将OutputStream转换为Writer

    数据流 DateInputStream DateOutputStream 分别继承自InputStreamOutputStream ,属于处理流,需要套接在InputStreamOutputStream类型的节点流上。提供了可以存取与机器无关的java原始类型数据(如:intdouble等)的方法

    Print PrintWriter PrintStream 都属于输出流,分别针对字符和字节。输出操作不会抛出异常,用户通过检测错误状态获取错误信息。有自动flush功能。提供了重载的printprintln方法用于多种数据类型的输出。

    Object

    序列化:将对象直接转换成字节流写到硬盘上或者网络上。序列化必用接口serializable。标记性接口,没有方法,做标记给编译器看,可以被序列化。

    transient关键字,修饰变量透明的,在序列化的时候不予考虑。

    externalizable接口  继承自serializable接口,可以自定义控制序列化过程

 

44. 系统默认编码格式GBKUTF-8比较省空间,常用于网络上传输

    System.in命令行键盘输入,阻塞进程,等待输入 

 

第九章 线程

 

45. 线程:一个程序内部的顺序控制流(一个程序中不同的执行路径)。机器中实际上运行的全都是线程。

    Main方法是主线程。

    进程:一个静态的概念,机器上的class文件、exe文件等。本身不能动,所谓进程的执行,是指进程里面主线程开始执行(main方法)开始执行

    DOS系统只支持单进程

 

46. 线程和进程的区别

    ①每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销

    ②线程可以看做轻量型的进程,同一类线程共享代码和数据空间。每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小

    ③多进程:在操作系统中同时运行多个任务(程序)

    ④多线程:在同一应用程序中有多个顺序流同时执行

 

47. java的线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法所定义的线程。可以通过创建Thread的实例来创建新的线程。每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。

 

48. 两种方法创建新的线程

    定义线程类实现 Runnable接口

    定义一个Thread的子类并重写其run()方法,然后生成该类的对象

 

49. sleep()调用者暂停若干毫秒

    join()调用者先执行完再给其他线程

    yield()调用者暂停,让给其他线程先执行

 

50. java提供一个线程调度器,按照线程的优先级决定调度哪个线程来执行,监控程序中启动后进入就绪状态的所有线程。

    优先级范围1-10,默认为5

 

51. synchronized 修饰方法,表示在执行这个方法的过程当中,锁定当前对象。而不是“同步方法”。

    Synchronized(this){}表示锁定当前对象

    对于锁定的对象(变量),其他未加锁的方法依然可以访问,其他加锁的方法不能访问

    互斥:加锁的方法,在某一时间段,保证只有一个线程进入到方法体中。不保证其他线程是否进入到另外一个方法中。

    主线程main中的方法,优先执行。(有待研究)

 

52.Object类的方法)wait() 使用后不再占有锁 ,需要notify()唤醒

    Thread类的方法)Sleep() 使用后仍然占有锁,睡一段时间后自己醒来

    只有使用了synchronized之后才有资格使用wait()方法

    this.wait();使当前的正在访问该对象的线程wait

    notify()叫醒一个正在该对象上wait的线程

阅读更多
文章标签: java
个人分类: java基础知识
上一篇UML统一建模语言
下一篇String s=new String(&quot;abc&quot;)创建了几个对象
想对作者说点什么? 我来说一句

Java 学习笔记Java学习笔记

2010年01月15日 25.63MB 下载

JAVA个人学习笔记

2009年12月03日 302KB 下载

Java学习笔记(必看经典)

2018年03月31日 37.54MB 下载

java学习笔记及源代码

2010年05月09日 2.73MB 下载

java 学习笔记

2011年09月13日 915KB 下载

java学习笔记,学习java的好帮手

2008年11月10日 1.48MB 下载

java学习笔记

2018年03月23日 31.58MB 下载

java笔记java笔记java笔记

2010年06月15日 719B 下载

Java学习笔记(源码)

2008年11月11日 175KB 下载

JAVA学习笔记(推荐)

2010年08月30日 59KB 下载

没有更多推荐了,返回首页

关闭
关闭