这是在学习Java时,记得一些笔记,有很多地方还没有完善,仅代表个人理解。
个人博客地址:小豆同学的个人站 (douzaixue.github.io)
(一)第一个helloworld程序
在一台啥也没有的电脑上,要想编译java,首先需要下载JDK,下载地址(PS:可能需要翻墙)。下载成功后,启动cmd指令管理器,输入javac,会出来一 堆文字,这说明JDK环境配置正常,接下来就可以快乐掉头发了。
在路径上建立一个文件夹,新建记事本,重命名为helloworld,打开文件,输入如下代码:
1 | public class helloworld{ |
之后将扩展名.txt改为.java 保存文件,此时文件夹中应该只有helloworld.java一个文件。打开cmd指令,找到对应路径下的该文件,输入如下指令:
javac helloworld.java
此时可以发现,文件夹中除了刚才的那个java文件,又多出来一个.class文件。java文件如果要运行,必须编码为class文件才能执行,之后输入如下指令:
java helloworld.class;
此时,屏幕上会出现Hello World!字样。
恭喜你,你的第一个程序完成了,接下来可以继续往下学习了。
(二)Java基础语法
1、Java简介
Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。由 James Gosling和同事们共同研发,并在 1995 年正式推出。
后来 Sun 公司被 Oracle (甲骨文)公司收购,Java 也随之成为 Oracle 公司的产品。
Java分为三个平台:
- JavaSE(J2SE)(Java2 Platform Standard Edition,java平台标准版)
- JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平台企业版)
- JavaME(J2ME)(Java 2 Platform Micro Edition,java平台微型版)。
2005 年 6 月,JavaOne 大会召开,SUN 公司公开 Java SE 6。此时,Java 的各种版本已经更名,以取消其中的数字 “2”:J2EE 更名为 Java EE,J2SE 更名为Java SE,J2ME 更名为 Java ME。
2、Java运行的两个核心机制
Ⅰ、Java虚拟机,JVM
JVM位于程序字节码和操作系统之间,它可以保证同一程序在不同操作系统上的运行,实现Java程序的跨平台性。
JVM是一个虚拟计算机,具有指令集并使用不同的存储区域。负责执行指令,管理数据、内存、寄存器;
.java文件编译生成.class文件,通过不同操作系统(UNIX、WINDOWS)的JVM来执行.class文件
Ⅱ、垃圾收集机制,GC
Java可自动回收垃圾,但回收不及时;
3、JVM 、JRE、JDK
JVM:如上解释,为java开发时的虚拟机
JRE:Java程序的环境
JDK:Java工具包
关系:JVM ∈ JRE ∈ JDK
4、Java基础语法
程序入口:所有的 Java 程序由 public static void main(String[] args) 方法开始执行。
大小写敏感:标识符 Hello 与 hello 是不同的。
源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)。
5、Java关键字与标识符
定义:被java语言赋予特殊含义,用作专门用途的字符串(单词)
特点:关键字中的所有字母均为小写
保留字:可能在后续的版本中被用作关键字的单词,但目前没有使用
Ⅰ、Java标识符命名规则
Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
- 标识符的首个字符以字母(A-Z 或者 a-z),美元符($)、或者下划线(_)开始
- 除首字母外,可以用字母(A-Z 或者 a-z),美元符($)、下划线(_)或数字的任何字符组合
- 关键字不能用作标识符
- 标识符是大小写敏感的
- 一些栗子:
- 合法标识符举例:age、$salary、_value、__1_value
- 非法标识符举例:123abc、-salary
6、Java基本数据类型
Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。 Java中默认整形为int型,声明long时要加“l”或“L”;默认浮点型为double型,声明float时要加“f”或“F”。
byte:
- byte 数据类型是8位、有符号的,以二进制补码表示的整数;
- 最小值是 -128(-2^7);
- 最大值是 127(2^7-1);
- 默认值是 0;
- byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
- 例子:byte a = 100,byte b = -50。
short:
- short 数据类型是 16 位、有符号的以二进制补码表示的整数
- 最小值是 -32768(-2^15);
- 最大值是 32767(2^15 - 1);
- Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
- 默认值是 0;
- 例子:short s = 1000,short r = -20000。
int:
- int 数据类型是32位、有符号的以二进制补码表示的整数;
- 最小值是 -2,147,483,648(-2^31);
- 最大值是 2,147,483,647(2^31 - 1);
- 一般地整型变量默认为 int 类型;
- 默认值是 0 ;
- 例子:int a = 100000, int b = -200000。
long:
- long 数据类型是 64 位、有符号的以二进制补码表示的整数;
- 最小值是 -9,223,372,036,854,775,808(-2^63);
- 最大值是 9,223,372,036,854,775,807(2^63 -1);
- 这种类型主要使用在需要比较大整数的系统上;
- 默认值是 0L;
- 例子: long a = 100000L,Long b = -200000L。
“L”理论上不分大小写,但是若写成”l”容易与数字”1”混淆,不容易分辩。所以最好大写。
float:
- float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
- float 在储存大型浮点数组的时候可节省内存空间;
- 默认值是 0.0f;
- 浮点数不能用来表示精确的值,如货币;
- 例子:float f1 = 234.5f。
double:
- double 数据类型是双精度、64 位、符合IEEE 754标准的浮点数;
- 浮点数的默认类型为double类型;
- double类型同样不能表示精确的值,如货币;
- 默认值是 0.0d;
- 例子:double d1 = 123.4。
boolean:
- boolean数据类型表示一位的信息;
- 只有两个取值:true 和 false;
- 这种类型只作为一种标志来记录 true/false 情况;
- 默认值是 false;
- 例子:boolean one = true。
char:
- char类型是一个单一的 16 位 Unicode 字符;
- 最小值是 \u0000(即为0);
- 最大值是 \uffff(即为65,535);
- char 数据类型可以储存任何字符;
- 例子:char letter = ‘A’;。
Define:
宏定义常量
1
final double PI = 3.1415927;
7、Java基本数据类型转化
Ⅰ、数据类型的高低如下:
- 自动类型转换:从低到高转换
- 强制类型转换:从高到低转换 或 浮点型到整形的转换等
- 隐含强制类型转换
- 整数的默认类型是 int。
- 浮点型不存在这种情况,因为在定义 float 类型时必须在数字后面跟上 F 或者 f。
1 | 低 ------------------------------------> 高 |
Ⅱ、数据类型转换必须满足如下规则:
不能对boolean类型进行类型转换。
不能把对象类型转换成不相关类的对象。
在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
转换过程中可能导致溢出或损失精度,例如:
1
2int i =128;
byte b = (byte)i;因为 byte 类型是 8 位,最大值为127,所以当 int 强制转换为 byte 类型时,值 128 时候就会导致溢出。
浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,例如:
1
2(int)23.7 == 23;
(int)-45.89f == -45
Ⅲ、数据类型间的混合运算
- 多种类型的数据混合运算时,系统首先自动将所有数据转化成容量最大的那种数据类型,然后再进行计算。
- 数字类型的运算中,多个相同数据类型变量参与的运算,变量首先转换成相对应的数据类型的默认类型(比如两个byte类型的变量相加,会先把两个byte类型的变量转换成默认的int类型之后再计算,得到的结果是int类型)。这种情况适用于变量的数据类型的容量比默认类型的容量小,(比如byte、short都比int小)。
- byte、short、char之间不会相互装欢,他们三者再计算时首先转换为Int类型。
8、Java中的数组
数组的几种定义方式:
1 | int a[] = {1,2,3}; |
9、Java中字符串的定义
1 | name = new String("就这???");//申请分配空间 |
(三)Java中的类与对象
1、对象、类、方法、成员
Java程序可以理解为用Java语言来描述世间万物的各种对象,而一个Java程序是由一个个的class类组成。
而关于类的组成,则有:
- 属性:对应类中的成员变量
- 行为:对应类中的成员方法
以人为对象进行举例:
1 | class Person{ |
比如事件:司机紧急刹车
类:司机、车
司机类:刹车的方法(函数);
车类:刹车的方法(函数)
司机类 通过 司机类的刹车的方法 调用 车类的刹车方法来实现刹车 实现刹车
2、类中方法的调用
前三个方法都是定义一些变量,最后一个才是主方法,是程序的入口。
1 | /** |
3、类中的方法属性
Ⅰ、方法属性的定义
定义格式:
修饰符 返回值类型 方法名(参数列表){
方法体语句;
}
说明:
修饰符:public,private,protected等。
返回值类型:return语句传递返回值。没有返回值用void
举个栗子:
1 | public class Person{ |
4、方法中的成员属性
Ⅰ、成员属性的定义
定义格式:修饰符 + 数据类型 + 属性名 = 初值;
其中,修饰符有以下简单的区别:
- private:私有变量,该属性只能由该class(类)中的方法访问
- public:公共变量,该属性可以被该类以外的方法访问
1 | 【例】 |
Ⅱ、成员变量与局部变量
- 成员变量:类中定义的变量
- 实例变量:不以static修饰,它在类实例化成对象之后才能使用
- 类变量:以static修饰,它不用类实例化对象,它可以通过 类名.类变量名 直接调用
- 局部变量:方法中定义的变量
- 形参:方法传递参数时定义的变量
- 方法局部变量,就是在方法内部定义的变量
- 代码块局部变量,在代码块内定义的变量
- 区别:
- 成员变量中的实例变量存在于对象所在的堆内存中,而所有局部变量只存在于栈内存中
- 局部变量作用范围结束后,变量空间会自动释放
- 成员变量有默认的初始值,而局部变量没有默认初始值,每次必须显式初始化
- 成员变量可加修饰符限定,局部变量不加修饰符
5、实例化对象
关于对象的的实例化
1 | public class Person { |
6、实例练习参考
【栗子1】
1 | /** |
【栗子2】
1 | /** |
7、补充和总结
Ⅰ、类中成员变量和方法的关系
- 在一个类中:类中的方法可以直接访问类中的成员变量,但static的方法无法访问非static的成员变量
- 在不同类中:先创建要访问类的对象,在用对象访问类中定义的成员。
Ⅱ、面向对象的设计思路
- 关于类的设计,即设计类的成员,属性,方法;
- 类的实例化(创建类的对象)
- 通过“对象.属性”、“对象.方法”执行
(四)有关方法的概述
1、方法的重载
就是同一个类中可以有多个相同名字的方法,前提是满足以下条件:
- 形参个数不同
- 形参的数据类型不同
- 形参的数据类型顺序不同
【例】
1 | public class overload { |
2、方法中的可变形参
当在方法传递参数时,可以传递0到多个形参个数。
格式为:数据参数类型…+形参名
当不可变形参和可变形参都存在的情况下,可变形参的参数要写在最后面,如下面的方法一
1 | public class args { |
3、方法中形参的传递
Java中方法参数的传递只有一种:值传递。即将实际参数值的复制品传入方法内,而实参本身不受影响
Ⅰ、JVM的内存模型
要搞懂形参传递的问题,首先要明白JVM的内存模型,以**Person p = new Person()**为例,如下:
- 栈区:存放基本数据类型(类似于int i)、对象的引用(即上述的p的值和p所对应的Person()的地址)
- 堆区:存放所有的对象(包括自己定义的对象和字符串对象。即上述的Person())
- 方法区:存放所有的static和class变量
- 总结:基本数据类型、值是存放在栈中,对象、值保存在堆中,栈中存放的是引用对象在堆中的地址
Ⅱ、基本数据类型形参的传递
1 | /** |
Ⅲ、对象形参的传递
1 | /** |
Ⅳ、总结基本数据类型和对象参数的传递
- 如果方法的形参是基本数据类型,那么实参(实际的数据)向形参传递时,就是直接传递该值,把实参的值复制给形参
- 如果方法的形参是对象,那么实参(实际的对象),向形参传递时,也是把值给形参,但这个给值是实参在栈内存中的值,也就是引用对象在栈内存中的地址
- 向形参传递数据时,基本数据类型和对象都是直接转递栈中的值,只不过基本数据类型在栈内存中存储的只是本身的值,而对象在栈中是存放的引用对象在堆内存中的地址
(五)Java中的各种概念
1、Java中的包
java中的包类似于文件夹,也是可以嵌套的,使用.来表示路径,如:map包下又一个data包,在data包下面又有一个age包其路径就可以表示为:map.data.age,在使用这个包时,在开头位置输入:import map.data.age的字样;
- 如果想调用age下面的Person类,则可以输入import map.data.age.Person
- 如果想调用age下面的所有类,则可也输入import mao.data.age.*
2、封装和隐藏
封装和隐藏是为了防止开放变量数据,被随便调用,出现不正确的结果,因此封装和隐藏数据是为了约束调用人大胆的想法。封装和隐藏的步骤如下:
- 将public类型的变量设置为private类型,这样调用人就不能直接访问该变量了
- 设置一个方法来专门对该变量进行赋值,从而达到约束的目的
1 | public class FengZhuang { |
3、Java中的权限修饰符
- class的权限修饰符只可以用public和default(缺省)
- 一个java文件中可以有多个类,但只能有一个public类型的类
修饰符 | 类内部 | 同一个包 | 字类 | 任何地方 |
---|---|---|---|---|
private | 可使用 | |||
default(缺省) | 可使用 | 可使用 | ||
protected | 可使用 | 可使用 | 可使用 | |
public | 可使用 | 可使用 | 可使用 | 可使用 |
4、Java的构造器
构造器就是实例化对象调用的方法,Java中构造器都是默认隐藏的,如果想使用自定义的构造器,则会替代默认的构造器。构造器最有用的地方就是可以在实例化对象时顺便初始化对象的变量。
构造器也是方法,所以构造器也可以重载。
1 | public class GouZao { |
5、this关键字
使用this可以方便区分实参和形参,this不能出现在static中。
1 | public class This { |
6、JavaBean
就是定义数据类型后,设置get和set的方法,值得注意的是,定义好数据类型之后,可以在eclipse中鼠标右键-source-generate getter and setter,示例代码如下
1 | public class This { |
7、继承
继承的意思就是说,可以新建很多子类继承到父类(又称超类)
- 子类可以继承父类的方法和属性
- 字类可以使用父类中定义的方法和属性,也可以创建新的数据和方法
- 在Java中,继承的关键字用的是“extends”,即子类不是父类的子集,而是对父类的“扩展”
- 字类不能直接访问父类中私有的(private)成员变量和方法
- 继承只可以单方向继承,即父类可以有多个字类,而字类无法有多个父类,但是子类还可以有子类
示例代码如下:
1 | /** |
8、方法的重写
区别于方法的重载,方法的重写是在子类中对父类中的方法修改,覆盖掉父类的方法,方法的重写要遵循以下的规则:
- 子类重写父类的方法,只是重新编写方法体的代码,而不能修改方法的名称,参数列表和返回值类型
- 重写的方法不能使用比被重写方法更严格的访问权限,如父类使用defult类型,重写方法就不能使用defult类型以上的public类型。
- 重写和被重写的方法须同时为static或同时为非static类型的
- 子类方法抛出的异常不能大于父类被重写方法的异常
示例代码如下:
1 | /** |
9、super关键字
super关键字类似于this关键字,它能够调用多级父类中的属性和方法,也能调用父级的构造器。同this一样,super不能用在static中。
关于this和super的区别如下:
区别 | this | super |
---|---|---|
访问属性 | 访问本类中的属性,如果本类没有此属性则从父类中继续查找 | 访问父类中的属性 |
调用方法 | 访问本类中的方法 | 直接访问父类中的方法 |
调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用父类构造器,必须放在子类构造器的首行 |
特殊 | 表示当前对象 | 无此概念 |
10、多态性
11、抽象类
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类不能实例化对象,其他和普通类一样,因其不能实例化对象,只能通过继承来进行操作
12、内部类和匿名类
13、异常处理
Java程序在执行时出错,编译不通过之类的就叫做异常,异常主要分为两类:
- Error:JVM系统内部错误、资源耗尽等严重情况(JVM内部错误)
- Exception:因编程错误或偶然外在因素导致的一般性问题(程序员问题)
【举例1】:数组越界异常
1 | public class Student { |
【举例2】:空指针异常
1 | public class Student { |
(六)图形用户界面-Swing
1、JFrame窗口
创建一个窗口程序,代码如下:
1 | import java.awt.Color; |
2、JDialog窗口
1 | import java.awt.Container; |
3、JLabel标签文字
1 | import java.awt.Color; |
4、JLabel标签图片
1 | import java.awt.Container; |
5、绝对布局
一个窗口从左上角为坐标原点,向右向下分别为横纵坐标像素。
使用绝对布局的窗口通常都是固定大小的,组件的位置和形状不会随着窗口的改变而发生变化。
1 | import java.awt.Container; |
6、流布局
从左到右排列,默认剧中对齐
1 | import java.awt.Container; |
7、边界布局
可以将组件放在所划分的东、南、西、北、中五个区域,组件大小会随窗口大小而改变
- 添加组件时,需指定区域,否则默认添加到中间区域
- 同一区域的组件会相互覆盖
1 | import java.awt.BorderLayout; |
8、网格布局
网格布局就是将组件按行与列组合成一个矩阵,放大缩小窗口时,组件也会进行改变;
1 | import java.awt.Container; |
9、网格组布局
网格组布局就是一个组件可以占用多个网格,网格组布局有以下几个属性:
gridx、gridy:调节组件所在的位置;
gridwidth、gridheight:调节组件的所占网格的长度和高度
fill
- NONE:默认所占网格中居中显示
- HORIZONTAL:水平填充
- VERTICAL:垂直填充
- BOTH:水平和垂直填充
anchor:调节组件放在上下左右或四个角或中间
insets:调节组件离上下左右边的距离
ipadx、ipady:组件的首选大小,横向比默认大ipadx,纵向比默认大ipady,不随窗口大小改变
weightx、weighty:保持与窗口间距的大小
每个属性都对应一个在主方法中都对应一个init,代码如下:
1 | import java.awt.Color; |
10、下拉框
1 | import java.awt.Container; |
11、列表框
1 | import java.awt.Container; |
12、文本框
1 | import java.awt.Container; |
13、密码框
1 | import java.awt.Container; |
14、文本域
1 | import java.awt.Container; |
15、动作与焦点事件监听器
动作监听:监听鼠标的点击、回车、按钮被触发等动作,在上面的程序中都有例子,这里就不举例了
焦点监听:就是监听动作监听器的有关信息
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!