序言
众所周知, 程序员需要快速学习新知识, 所以就有了《21 天精通 C++》和《MySQL - 从删库到跑路》这样的书籍, Java 作为更 "高级" 的语言也不应该落后, 所以我就写一个《极. Java 速成教程》, 让想学的人能够快速学习 Java(手斜).
本文大概分三大部分:
编程基础知识
面向对象思想
数据类型
运算符
流程控制
Java 语言特性
Java 高级特性
本文请逐字理解文本内容, 本文仅供理解和学习 Java 编程, 不可作为概念性参考
本文是阅读《Java 编程思想》后的读后感
面向对象思想
何为面向对象
Java 是一个从设计之初就遵循面向对象思想的语言, 因此而有着诸多面向对象的特性, 那么问题来了, 面向对象指的是什么?
面向对象, 不是指的脸超女朋友, 而是说编程的时候, 你所操作的一切事物都是 "对象", 假如说 Java 程序员是个搬砖工, 那 Java 操作的对象就是搬砖工手里的砖, 一块砖就是一个对象, 一堆转就是一堆对象, 诸多同样的对象可以用一个概念来概括, 这个概念就是 "类".
先在我们可以思考砖是个什么东西, 也就是砖的 "概念(类)": 砖, 由土烧制而成, 可以用来砌墙, 铺地和垫桌角, 有一定的重量和体积, 能被搬被砌. 仔细分析这句定义, 可以发现能分为 4 小句:
砖是由土烧制而成. 也就是说, 一个类都是从另一个或多个类继承发展而来, 也就是 "继承 (extend) 和组合自另一个或多个类", 在 Java 中, 所有类都继承和扩展自 Object 类, 在自己写的程序中, 一个类可以继承和扩展自官方的类, 别人写的类和自己写的类.
砖可以用来砌墙, 铺地和垫桌角. 也就是同一个类可以根据不同的需求去加工处理, 修改为不同的 "形状", 添加不同的属性, 在不同的地方起到不同的作用.
砖由一定的重量和体积. 也就是说每个类都有其属性, 但是对于同一种属性, 他们的值未必相同, 正如每个砖的重量和体积都可以不同.
砖能被搬被砌. 也就是说每个类都有其功能, 属性是一个类静态的描述, 而功能 (或者说方法) 则是一个类动态的描述.
将许多个 "砖" 一样的对象搭配组合, 堆垒到一起, 就可以构建起程序的这栋房屋, 实现整体的功能.
Java 中类的几个特点
Java 中的类有几个特点
单根继承, 也就是说某一个类只能直接继承自另一个类, 就像砖只能由土烧制而成, 即土→砖, 然而除了土, 砖的烧制过程中还需要加其他的配料比如防火原料, 也就是说除了直接继承, 还可以添加其他类到一个类中, 这种方法叫通过接口 (interface) 进行继承.
访问控制. 对于一个类来说, 你只能看到一个类想让你看到的部分. 就像一个砖, 你只能看到砖的表面, 不能看到它的内里, 除非敲开他, 但是在 Java 中, 这是不被允许的. 一个类想让你看到的部分和不想让你看到的部分由不同的关键词进行控制:
public 对于所有对象都公开的内容
private 只有自己可见的内容
protected 只有自己和自己的子孙可以看到的内容
default 只有自己的亲戚 (同一个包) 可以看到的内容
我们不用关心他们内部什么样子, 我们只需要关心我们需要的, 暴露在外面的东西, 以及对象能正常工作就行.
"像" 就是 "是". 对于一个类来说, 如果长得像一个东西, 那就可以看作是一个东西. 就像儿子像父亲, 父亲能干的儿子也能干一样, 一块防火转是一个砖, 那他也有砖的所有属性, 也能被垒起来. 而一个具有垒起来方法的对象看上去能垒起来, 那他就能像砖一样被垒起来.
static 属性. 对于一个类来说, 有的属性和方法可以是 static 也就是静态的, 这种属性和方法不是描述一个类的对象的, 而是描述一个类的. 就比如可以对所有的砖执行统计数量操作, 对于一个砖头让他统计同类的数量是不恰当的, 但是对于一堆转, 让这堆砖告诉你有多少块是可行的.
对象生命周期管理. Java 语言的使用者不用关心 Java 对象是怎么诞生的, 怎么消亡的, 只需要在需要时 new 一下, 创建一个对象即可, 使用完以后的垃圾丢到哪里, 那是 Java 高级特性需要研究的东西.
Java 中的类之上具有包 (package) 的结构, 包是具有层次的, 如 java.lang.Math 就表示 java 下的 lang 包下的 Math 类, 这个层次结构可以有好多层, 一层一层深入, 所以可能这个名字会很长. 在使用某一个包中的某一个类的某些内容时, 需要使用 import 进行导入, 如果需要导入某个包下的全部, 可以使用通配符., 如 java.lang..
Java 编程需要关心的点
只要想好这个类和它的对象应该怎么设计, 怎么正常运行即可, 其他语言的包袱, 甩掉即可
数据类型
一切都是对象, 而根基只需要几个
当 Java 使用者需要一个对象时, 这个对象在内存中的位置时我们不用管也没法管的. 但这个对象是怎么来的, 却是可以思考的. 就像房子是砖垒成的, 砖是由土烧成的, 那土是什么构成的呢, 这么追究下去, 追究到最后就成了重子和轻子了, 但是我们不必追求这么细, 就像 Java 中我们知道一切对象都有 Object 这个 "祖宗", 但是我们不需要凡事都请动这个祖宗, 它有几个子女是我们常用的, 也就是 "基本类型":
类型 | 大小 | 包装器 | 初始值 |
---|---|---|---|
boolean | true/false | Boolean | false |
char | 16 bit | Character | '\u0000' |
byte | 8 bit | Byte | (byte)0 |
short | 16 bit | Short | (short)0 |
int | 32 bit | Integer | 0 |
long | 64 bit | Long | 0L |
float | 32 bit | Float | 0.0f |
double | 64 bit | Double | 0.0d |
void | Void | void |
这些基本类型的大小都与其位数 n 有关, 最小值为 - 2n-1, 最大值为 2n-1-1,float 和 double 遵循 IEEE754 标准.
除了基本类型, 还有字符串 String, 高精度整数 BigInteger 和高精度浮点数 BigDecimal 等常见类.
对象应当被管理
一个对象, 给他个称号, 就可以根据这个名字喊他做各种事, 就像家里人可以喊你小名让你干活一样. 但是当出了家里, 可能有好多人跟你重名, 这会带来困扰, 因此是不被允许的, 而在外面叫你的小名, 这也会带来尴尬, 也就是说, 这个名字超出了作用域, 在 Java 中, 一个称号 (或者说引用) 的作用域是从这个命名的声明到所在花括号的结尾. 当然如果不关心这一点也没问题, 因为 IDE 会提醒你这里出了问题.
当一个对象有了它的称呼以后, 就可以安排他做好多的事情了, 无论谁喊, 只要是喊到, 就可以用. 在作用域范围内的所有调用都可以通过这个名字实行, 而你也可以再给这个对象起另一个名字, 这多个名字都是指的同一个对象, 当处理不当时, 这会带来一些问题, 比如一个喊你张三的人给你图了个花脸, 别人喊你李四把你喊过来以后也会看到一个花脸.
对于一堆相同类型的对象, 可以用一个容器装住他们, 方便我们管理和使用, Java 中提供了多种类型的容器, 有最基本的数组, 也就是一串连续的空间去装一样的对象, 还有其他的诸如 set 和 map 之类的容器可以装, 这一点可以在后面进行详细讨论.
运算符
运算符按照字面语义理解就好
运算符有其优先级, 也有短路的特征. 优先级就是说先乘除后加减, 短路就是逻辑运算时当直接可以产生结果时就不再继续运算.
运算符有以下几个:
+. 加号, 数字的累加, 字符串的连接, 将较小类型的数字提升为 int 类型.
-. 减号, 数字相减. 负号.
*. 乘号, 数字相乘.
/. 除号, 数字相除, 给出结果的整数部分, 直接截断小数, 不会四舍五入.
%. 求余, 数字相除求余数.
++ 自增,-- 自减, 当出现在对象前面时先运算再输出值, 当出现在对象后面时先输出值再运算.
>,<,>=,<=. 大于, 小于, 大于等于, 小于等于. 顾名思义.
== 判断相等, 对于 Java 来说, 这是容易使人困扰的一点, 因为除了在判断基本类型对象是否相等时以外,== 仅仅为判断别名所指向的对象是否为同一个, 而不关心对象的属性是否相等. 如果要判断 String 等官方封装好的类型, 就要用到 equals()方法, 但是对于自己定义的类来说, 如果没有重新定义 equals()方法, 就会和 == 一样, 对引用对象进行判断, 而不是对对象的属性进行判断.
&&,||,!. 逻辑运算符与或非, 对 boolean 值进行判断, 两边都 true 时 && 结果为真, 两边有一个为 true 时 || 结果为真,! 是对 boolean 对象的逻辑值进行颠倒.
&,|,^,~. 按位操作符, 对数字类型进行按位的与, 或, 异或和非操作, 与, 或, 异或是对两个对象进行操作, 非是对一个对象进行操作.
<<,>>,>>>. 移位操作符, 就是将操作数按位进行移位, A※※B 就是将 A 往箭头方向移 B 位. 如果是负数,>>在左侧补 1,>>>在左侧补 0.
=. 数字赋值, 或者是给一个对象起别名, 或者是将另一个别名添加到一个对象上.
+=,-=,*=,/=,&=,|=,^=,>>=,>>>=,<<=. 比较类似, a※=b 就是 a=a※b. 当>>>=byte 和 short 时, 转化成 int 进行处理然后截断, 可能产生不正确的结果.
指数计数法: AeB 代表了 Ax10B, 如 1.39e-43f 代表 float 的 1.39x10-43.
?:. 这是个三元运算符, 如 A?B:C 就表示如果 A 的逻辑结果为真, 就执行 B, 否则就执行 C.
直接常量, 就是直接的数, 如 200D,0x200. 其规则是如果后面跟 D 表示 double,F 表示 float,L 表示 long, 前面跟 0 表示 8 进制数, 0x 表示 16 进制数.
操作符使用时容易出现的问题
类型转换
(A)B 可以将 B 强制转化为 A 类型, 如果是从较小的类型转化为较大的类型, 将不会带来问题, 但如果是从较大的类型转化为较小的类型, 则会带来信息丢失的问题. 自定义类的转换同理.
截尾和舍入
对于浮点数来说, 强制转化为整形时, 会舍弃小数部分, 如果要获取舍入的结果, 需要使用 java.lang.Math 中的 round()方法.
流程控制
Java 是一种面向对象的语言, 但其执行过程依旧时顺序的, 在顺序执行的程序中, 会进行一些选择分支和循环操作.
选择
Java 中可以使用 if-else 和 switch 进行分支选择.
if-else
形如
- if(A){
- B
- }else{
- C
- }
就是如果判断条件 A 为真, 则执行 B, 否则执行 C.
switch
形如
- switch(A){
- case 1: B;
- case 2: C;break;
- case 3: D;break;
- case 4: E;break;
- ...
- }
即如果判断条件 A 为 1, 则执行 B 然后执行 C 然后中断该代码块, 如果判断条件为 2 则执行 C 然后中断该代码块, 如果判断条件为 3 则执行 D 然后中断该代码块, 等等.
循环
循环有 3 种形式: while,do-while 和 for.
while
形如
- while(A){
- B
- }
对判断条件 A 进行判断, 当判断条件为 A 时, 多次执行 B 代码.
do-while
形如
- do{
- B
- }while(A)
先执行一次 B 代码, 然后对判断条件 A 进行判断, 当判断条件 A 为真时, 循环至花括号头部执行 B 代码.
for
形如
- for(int i=0,j=0;i<100;i++,j++){
- B
- }
首先对第一个; 前面的部分执行, 常见于循环控制对象进行初始化, 多个对象可以使用, 进行区分, 然后对; 间的循环控制条件进行判断, 如果条件为真则执行下方代码块, 最后对; 后的第三部分执行, 比如对循环对象进行自增操作等. 实例中就是先对 i 和 j 进行初始化为 0, 然后判断 i 是否小于 100, 如果为真则执行 B 代码, 最后执行 i 自增和 j 自增, 然后判断 i 是否小于 100, 如果为真继续循环, 该代码最后将执行 B 代码段 100 次.
在编程时, 循环常在数组等可迭代对象上进行. 可迭代就是可以从前到后顺序走一遍. 对此, Java 提供了一些便利的语法方便开发. 形如
容器 A;
- for(int i:A){
- B
- }
就是说对于容器 A, 迭代遍历一遍, i 会在每次循环中引用到 A 中的每个对象, 然后执行 B 代码块. 假如容器 A 中有 100 个对象, 那 B 就会被执行 100 次.
返回
return
结束该语句所在函数, 返回返回值.
返回值类型由函数定义决定, 如果不匹配且无法兼容则会 IDE 报错.
Java 的与众不同
Java 的流程控制中没有 goto 语句, 但是通过 break 和 continue 语句, 实现了从深层循环中跳出的功能. 通过在循环前标记 label:, 然后使用 break label 和 continue label, 即可跳出循环到指定位置或者是跳出本次循环到指定位置.
- label1:
- while(true){
- label2:
- while(true){
- continue label1;// 结束本次循环, 跳转到外循环继续循环
- break label1:// 结束外层循环
- }
- }
感慨
Java 的基本语法, 与其他的语言有相似之处, 也有不同之处, 但编程本来就是一种实践的技能, 纸上得来终觉浅, 绝知代码要手撸, 还是实打实的写代码才可以将知识转化为能力. 以及, 文章真难写.
来源: https://www.cnblogs.com/CoveredWithDust/p/11899457.html