Skip to content

DearDon/LearnJavaSE

Repository files navigation

learnJavaSE

一直以来觉得javaSE基础没好好学,趁此机会决定好好学习一遍,为自己以后的学习发展做铺垫。学习基于《Java语言程序设计》(焦玲,机械工业出版社)。记录笔记时间始于2015/06/09。

chapter01 初识Java

这部分主要是Java的一些背景,基本概况。以及详细介绍了安装开发环境——JDK和JCreator的安装使用。jdk安装已经很熟了,而自己学习本书为了练习手敲代码,不准备用IDE,而仅用文本编辑器,所以不用JCreator。该章内容基本略过。

chapter02 Java语言基础

这部分讲了Java中的各基本组成部分——符号、基本数据类型、表达式以及数据类型转换。亲测需要注意的是:

  1. 基本数据类型包括整数类型(long,int,short,byte)、浮点类型(float,double)、字符类型(char)、布尔类型(true,false)。记住不包括String(引用类型),所有的基本数据类型都是内存占用明确的,直接声明使用即可,不用通过new申请引用地址指向的内存空间。基本数据类型在面试时经常被问。
  2. 关于类型转换部分,一般低精度(小范围)的可自动转换为高精度(大范围)的类型存储,反过来则可能溢出报错或提醒。整数常量如123通常默认都是int类型(即占4字节),只要不超过所表示数的范围,将其赋值给byte,short,int,long型的变量都是可以的,想指定用long型(占8字节)表示整数常量要在其后加L,如123L。java中默认的浮点数如123.1都是double型的,且只能将其赋值给double型变量,不能是float型,即使没有超过float型能表示的范围。要将常量指定为float型需在其后加F(f),如123.1f。由上知123.1d123.1在java中是等价的。有意思的是12==12L的布尔值为true,而12.1f==12.1的布尔值为false,因为二进制表示十进制数的问题,计算机中整数类型在表示范围内是精确值,且与整数一一对应,而浮点型表示都是近似值。所以doublefloat型值表示的数学上同一数在内存中字节里存的"近似值"却可能不同。
  3. 布尔型在java中只能为truefalse,不像c中还可以用不同整数值代表并赋值。

chapter03 Java程序流程控制

这部分首先讲了条件、循环两大流程语句,然后还讲了方法的定义与使用及一些常用的Math类数学方法。本章没有什么隐晦的地方,注意的是switch语句的case后接的执行语句后要接break来跳出switch,否则之后的语句都会执行。另外发现java中数学计算也挺丰富的,运算符中直接有求余运算%。Math类中还提供了各种数学计算方法,如常用数学常数圆周率、自然指数的定义。绝对值函数Math.abs(double),四舍五入取整Math.round(double),舍小数取整Math.floor(double),进一取整Math.ceil(double),返回两数中较大(或小)的数Math.max(double,double),返回0-1之间的随机double数Math.random(),以及三角函数计算等等,其中上面标识double的,都可以换为更低精度的如float或int等数值类型,且这些数学方法都是静态方法,无须实例直接使用。

chapter04 数组和字符串

这部分讲数组和字符串这两种引用数据类型。

详细介绍了一维和多维数组的声明及赋值过程,一维数组中数据在空间中是连续存放的,但在Java中把二维数组看成是数组的数组,空间不连续,所以不需要二维数据每一维的大小相同。

字符串在java中使用比c中方便(c是直接用数组实现,没有字符串类型),并提供了很多字符串类的操作方法,如length()返回字符串长度,charAt(int index)返回字符串第index个字符,indexOf()返回指定字符或子字符串在字符串中的位置,subString()从字符串中提取一段子字符串,使得字符串的使用非常灵活。比较重要的是区分字符串比较时equals()==的区别,前者比较字符串内容是否相同,后者是直接比较它们的引用地址是否相同。java中还可方便地实现字符串与其它基本类型间的转换(输出语句其实就用了这个功能,默认将所有其它基本类型变量都转为String进行输出)。

chapter05 面向对象的程序设计概念

本章开始介绍面向对象编程的基本概念,包括类,对象的定义与创建。还介绍了与之相关的引用在未赋值时调用的情况。关于本章经自己亲测有以下需要注意的方面:

1. 类继承时构造函数的行为

通常类继承时会继承各种父类方法或变量,但有一特殊的方法就是构造方法,它的继承需要注意不然会导致编译出错。因为构造方法是在初始化对象时就要执行的函数,当子类声明初始化时,为了继承得到父类的各种资源会先执行父类的构造方法以申请一个父类对象,然后再执行自己的构造方法以在父类对象基础上通过覆盖、重载、扩充以得到正确的子类对象,所以说子类的构造方法中第一句肯定是执行父类构造方法(当没有显示写出时会默认隐式执行父类构造方法)。但是,由于此时还没有构造出对象,所以执行构造方法前子类完全不知道父类中构造方法需要何种参数,java规定在没有显示指出时,它默认隐式引用的都是无参的构造方法比如说。所以如果子类的构造方法中没有显示引用父类构造方法时,一定要确保父类中构造方法中有无参的版本。当未显示定义构造方法时会默认隐式生成一个无参构造方法,但显示定义了任意构造方法后便不会自动生成隐式无参构造方法,这时候如何需要无参构造方法就要自己定义了。子类继承时有时没有显示指定父类构造方法,为了避免报错,在父类中不管隐式还是显示,得定义一个无参构造方法。

2. 还有一点概念问题

因为方法或类的成员变量有public,protected,friendly,private四种权限,其中friendly是无修饰符时的默认权限。这四种权限范围由大到小,其实也可以理解成是它们的可见范围由大到小。对于这四种权限的内容:

  • public对所有类可见,
  • protected对不在同一包中且非子类的类不可见,
  • friendlyprotected不可见范围基础上还对子类也不可见,
  • privatefriendly不可见范围基础上还对同一个包中的类不可见,仅仅在本类中可见。

由于java中最大的范围就是包,对于普通类(也叫外部类)而言,其外层目录就是包,所以普通类间的关系要么属于同一包,要么不属于,所以权限范围只有friendlypublic有意义,前者表示同一个包中的类间可引用,后者刚是不同包的类也可见。所以java中普通类前不能用private,protected修饰。其实类除了直接定义在包中,还可以定义在另一个类或方法中,这种类称为内部类,它的外部范围就和其它变量或方法一样的,所以可以有public,protected,friendly,private这四种权限。

chapter06 类的封装、多态和继承

本章讲解面向对象特征中类的这三个重要特性,对封装和继续要注意的是各成员变量或方法的权限修饰符,以使该部分内存中的内容在封装或继承时有正确的权限,以满足封装或继承的需要。 关于多态,对类和方法有不同,对类而言是指父类作为对象的数据类型,而子类作为数据实体的情况;对方法又可分为方法重载和重写,重载是指一个类中多个相同方法声明,但是要求的输入参数不同,调用时会自动根据所给参数合适重载,重写是指子类声明了与父类一模一样的方法(包括输入参数和返回类型),这时子类的方法会重写覆盖掉从父类继承的该方法。

chapter07 接口和包

本章讲了抽象类、接口还有包三部分内容。

1. 抽象类

抽象类其实和普通类没有本质区别,它只是多了一个abstract标志,用来提醒开发人员该类不能直接实例化,因为有些抽象方法需要重写实现。事实上,抽象类中甚至可以没有抽象方法,普通类可以通过加一个abstract修饰符变成抽象类。当抽象类中没有抽象方法时也可以直接去掉abstract变为普通类。所以抽象类中除了可能有abstract修饰的没有方法体的抽象方法以及抽象类不能直接实例化(继承为普通类才行),它的所有功能和写法都和普通类一模一样。经自己验证,由于静态方法不需要实例化对象,可以直接在其它类调用抽象类的静态方法。并且,由于一个程序执行入口方法main方法时不需要实例化该main方法所在类的一个对象,所以main方法所在的类也都可以申明为abstract,程序可以正常运行。但是abstract的初衷就是为了防止开发人员忘记父类中有方法必需要重写实现,作为提醒用的,作为好习惯再没有这种需要的时候不要滥用abstract

2. 接口

接口各类本质是有差别的,首先接口间可以多重继承,但是只能继承一个类或被一个类继承,这多重继承是接口的出现的初衷。在c++中由于类可以多重继承所以没有接口,而java中的类只能单一继承,接口就是为了完成多重继承出现的。其次为了多重继承的安全性,接口相对于类做了很多限制:

  1. 不能直接实例化,这一点和抽象类有点象,接口必须被implements为类之后才能实例化,implements时必须要将接口中的抽象方法全部重写实现。
  2. 接口中的方法必须全部为抽象方法,没有方法体,由于方法均为抽象的,所以接口中抽象方法不需要abstract修饰,且方法不能为static的。
  3. 接口中的成员变量默认均是final static类型的,所以在声明时必须被赋值成为常量,其值可以在该接口未被implements时通过静态变量调用的方式调用,但值不能被更改。这些限制使得接口本身可以实现的功能基本没有,但是这样简洁的定义可以保证多重继承时更安全(防止各种不注意的冲突覆盖重写)。所以接口更像是一个计划,告诉开发者该做什么。

3. 包

包这一部分,之前已经试验清楚了,注意在包中的类的最小单元是包,所以运行或被引用时要在包的上层目录,还不能直接在类所在目录。编译时加-d .可在当前目录生成包对应用的目录结构。另外import语句其实是引入命名空间而已,因为包中的类的命名要包含包,通常都会很长,通过import语句指定该类的全名,在程序中就可以去掉包名,使得程序更简洁了。程序中本质上是否能引用到一个类关键在于该类(或该类所在的包)是否存在于classpath路径下,import只是简化命名的作用。

最后提一下thissuper的用法,this提供本类,通过this可调用本类的成员变量,通常在有作用域覆盖时使用,比如在局部范围内有与成员变量重名的局部变量,这时局部变量默认会有优先权,通过this可以在该局部调用成员变量。super是调用父类的成员变量或方法,通过它可以调用被子类覆盖隐藏的成员变量或方法,另super(参数)表示 调用父类构造方法。

chapter08 异常处理

异常通常是指程序运行过程中出现的非正常现象,当然异常也可能出现在编译过程中。但是异常不应当指明显的程序语法错误,如float a=14.4;这种可以完全避免的问题。关于异常的理解现在还不太全面,以后有再补充。

能被抛出和捕获的异常必须都是Throwable类的,Throwable类又有ExceptionError两个子类。一般Java程序只要求对Exception子类的异常进行处理。继承于ExceptionRuntimeException称为运行时异常,编译器不地它进行处理,而在程序运行时捕获处理,其它的Exception子类如IOException称为非运行时异常,在编译时java编译器要求程序必须捕获该异常,否则编译不通过。

try语句后可以有多个catch语句,多个catch语句按顺序匹配捕获异常,只要有一个捕获到了后就会忽略掉后面的catch语句。所以catch语句应该按顺序先捕获最特殊,再一般化。另外注意try之后能抛出的是直接语句的异常,如果是调用方法,必须在方法内先跑出。

当一个方法内部会生成异常,但是不会在方法内处理时,可在方法申明后加上throws ExceptionType1 ExceptionType2 ...语句,提示该方法遇到这些类型异常时直接抛出给上层,自己不处理。throw语句则是主动抛出生成的异常,因为异常也是类,可以在需要时实例任何Throwable或其子类型异常对象e,然后用throw e抛出该异常。此外,因为每个程序需要不同,可能需要用到一些很奇特的异常,如出现不和谐的词语就算异常等,这个时候java中可能没有内定这种异常。既然异常也是类,那当然也可以自定义异常类型,只要继承相应的类如Exception就行。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages