Java基础入门

距离上一次写System.out.println("Hello World");已经过去了很长一段时间了,然而学习安卓还是得掌握Java的基础知识,毕竟归根到底Android也只是一个框架而已,因此这里复(yu)习Java的基础知识,主要是通过对比PHPJavaScript来进行整理。

<!--more-->

参考:

1. 语言背景

1.1. JVM

JVM是Java虚拟机(Java Virtual Machine),可以理解为一个虚构的计算机,最主要的特性就是与平台的无关性:Java的编译程序只需要将源码编译成可以在JVM上运行的目标代码就可以了,而Java程序在不同的平台上运行时不需要重新编译。

JVM是学习Java必须掌握的知识,这个后面慢慢搞明白。

1.2. 目录结构

Java代码的源文件后缀名为*.java,Java的代码通过类来进行组织(除了声明和引入包名,其余的代码都必须出现在类中),一个源文件中包含一个或多个类,一个源文件只能导出一个主类(通过public class声明的那个类,换句话说,public声明的类必须独立存在于一个源文件中)。

需要注意的是源文件名必须和主类名称相同(否则编译就会出错),我感觉直接从语言方面限制类名是一个很奇怪的设定,在PHP中可以将命名空间映射到对应的文件名然后加载对应的类,但是文件名和类名也不一定是完全相同的。

1.3. 开发环境

IDE上纠结了半天,尝试了Eclipse之后最终选择了的 Intellij IDEA,主要是一直Intellij全家桶,相关配置啥的都比较熟悉。 PS:向用编辑器写代码的大佬低头...

2. 基础语法

2.1. 数据类型

分类 Java是强类型语言,其数据类型主要分为基本数据类型和引用数据类型(这个分类跟JavaScript很像)

  • 基本数据类型
    • 整数类型byte,short,int,long
    • 浮点数类型float,double
    • 布尔类型boolean
    • 字符类型char
  • 引用数据类型
    • 对象

隐式类型转换 相比与JavaScript中的各种花式隐式数据类型转换,Java中的隐式数据类型转换(也称作自动转换)主要是指数字类型按容量从小到大的自动提升

byte,short,char --> int --> long --> float --> double

这里需要注意的是byte, short和char都是平级的,因此无法自动转换,可以使用强制类型转换。

强制类型转换 在Java中强制类型转换是非常常见的,如果你明确知道数据是可以用该数据类型来表示的,可以用强制转换,一般用在将高级变量转换为低级变量(可能造成精度丢失)。强制类型转换的父类和子类之间的转换是十分常见的,后面会着重提到。

2.2. 执行流程

顺序,分支和循环

分支 分支包括ifswitch

  • if条件表达式的结果必须强制转换为boolean类型,否则无法通过编译。
  • switch中的变量类型可以是byteshortint 或者 char,现在也支持字符串,对应的case必须为字符串常量或者字面量

循环 循环包括while,do-whilefor,以及跳出循环的continuebreak,使用方法跟JavaScript基本相同。 此外Java提供了一种用于数组的增强型for循环,用于遍历数组

2.3. 数组

Java中的数组是用来存储固定大小的同类型元素,这跟C++相似。需要注意的是声明数组字面量采用的是{}而不是[],数组索引也是从0开始的。

int [] arr = {1, 2, 3, 4, 5};
for(int x : arr ){
    System.out.println( x );
}

2.4. 函数

Java中没有函数,只有方法,切记切记。

2.5. 其他

此外还有一些零碎的语法:

  • 标识符命名大小写敏感,不能以数字开头,不能使用关键字
  • 关键字与C++比较相似,用IDE的话也不用太在意这个问题了
  • 支持多行注释/**/和单行注释//
  • 支持++--自增增减操作符
  • 支持>>>按位右移补零操作符
  • 运算符优先级这个问题也比较相似

3. 对象

Java是一门纯粹的面向对象的语言(这句话貌似见了很多次),除了包的声明和引用之外所有代码都只能出现在类(接口)中。

3.1. 变量

类中的变量主要分为了三类:局部变量,成员变量和类变量

局部变量 指的是在方法内部声明的变量,其作用域仅存在于方法中,参数也属于局部变量。局部变量在方法执行时创建,并在方法调用结束后销毁。 局部变量在使用前必须进行初始化操作。

实例变量 实例变量即成员变量,指每个实例对象都具备的变量,同个类下多个实例对象之间的成员变量互不影响。 实例变量在创建对象的时候实例化,且可以在方法中直接调用(如果与局部变量同名则可以使用this来显示调用成员变量) 实例变量总是会有默认值的(根据数据类型不同其默认值也不一样)

类变量 指某个类持有的变量,即声明为static类型的静态变量。多个对象共享同一个静态变量。可以把静态变量看作是特殊的实例变量,因此它也总是有默认值的。

3.2. 方法

函数签名包括参数类型,参数个数,参数顺序,编译器通过函数签名调用对应的方法(重载)。

Java中所有的赋值和方法调用的参数都是“按值“处理的,引用类型的值是对象的地址,基础类型的值是其自身(这句话貌似在《你不知道的JavaScript》中也见到过)

程序的的入口方法是public static void main(String []args){}

3.3. 包

Java使用包对类和接口进行分类,防止命名冲突以及限制访问权限,可以理解为命名空间。

创建包 包声明应该在源文件的第一行,每个源文件只能有一个包声明,这个文件中的每个类都应用于它

package com.example.txm

引入包

// 导入类,最常用的做法
import xxx.xxx.xxxClass 
// 导入整个包
import xxx.xxx.xxx.* 
// 导入静态成员
import static xxx.xxx.*

需要注意的是:

  • 在同一个包中,一个类想要使用本包中的另一个类,那么该包名可以省略
  • Java本身就内置了一些包(比如java.lang等),不需要显示引入就可以直接使用的。

3.4. 垃圾回收

Java中的实例对象都保存在堆上,而对象的变量名只是保持对某个对象的引用(比如堆地址?),可以改变某个变量的引用(当然得保证类型相同或兼容)。 如果堆上的某个对象没有被任何变量引用(计数器置为0),那么该对象就会被垃圾回收器回收,具体的细节目前并没有深入,JavaScript中也是采用相同的计数垃圾回收机制。

4. 面向对象

面向对象的核心就是抽象,封装,继承和多态(多么学术的回答~),在Java中能够完美的实现。下面是《Head First Java》中关于面向对象的一些建议,这里一并整理出来:

  • 找出具有共同属性和行为的对象(抽象)
  • 设计代表共同状态的类,用继承来防止出现重复的代码(继承)
  • 对象可以提供统一的接口供外部使用,而隐藏内部的数据和方法实现(封装)
  • 决定子类是否需要让某项行为有特定的不同的运作方式(多态)
  • 通过寻找使用共同行为的子类来找出更多抽象化的机会,实现类的继承层次(继承)

4.1. 抽象

这是一个仁者见仁的问题,我现在就是一个菜鸡~这里先撤了...

4.2. 封装

通过封装,对象只向外部暴露功能接口,而隐藏内部实现。这样能够保证每个类都有较好的独立性,便于程序维护

  • 从使用者的角度看,如果需要替换某个类,只需要保证替换类提供了相同的接口,完全不需要去更改内部的实现代码
  • 从维护者的角度看, 或者要优化某个类,只需要保证暴露的接口不发生更改,内部实现的修改不会影响外部的功能

4.3. 继承

如何设计父类是一个问题,如何设计需要继承的子类是另外一个问题。需要明白的是:继承概念下的IS-A是个单向的关系。

子类可以继承父类的成员,包括变量和方法;反之,父类可以通过存取权限决定子类是否能够继承某些特定成员

4.4. 多态

Java中的多态简直可怕。 在多态下,变量引用和对象可以不相同,换句话说,运行多态时,引用类型可以是实际对象类型的父类,参数和返回类型也可以是多态

4.5. 访问修饰符

除了常规的private,protected,public之外,Java还提供了default的访问修饰符。如果不对成员变量和方法使用任何访问修饰符,则其默认为defaultdefault 修饰的类型或成员只能被自己和同一个包里的(不包括子包)其他类型访问。

下面是关于访问修饰符的总结(这个表示从网上拿过来的,貌似已经找不到出处了)

类内部 本包 子类 外部包
public ~ ~ ~ ~
protected ~ ~ ~
default ~ ~
private ~

5. 内置对象

Java提供了大量有用的内置对象,比如日期,数学计算,正则表达式,常用的抽象数据类型等。相关的东西在使用中慢慢学习,因此又得准备一本手册(/掩面)。

5.1. Date

与日期相关的类有

  • Date封装当前的日期和时间
  • SimpleDateFormat格式化分析日期
  • Calendar设置和获取日期数据的特定部分

5.2. Math

封装了随机值,取整等方法

  • Math.random
  • Math.ceil
  • Math.floor
  • Math.round

6. 小结

简单过了一遍Java基础,很多东西都只是有了一个概念而已,在今后的学习中慢慢填坑吧。