Java 笔记
Java 入门
1、C & C++
- 1972年C诞生
- 贴近硬件,运行极快,效率极高。
- 操作系统,编译器,数据库,网络系统等
- 指针和内存管理
- 1982年C++诞生
- 面向对象
- 兼容C
- 图形领域,游戏等
- 何为编程
- 人与计算机交流的过程
- 让计算机解决某个问题使用某种程序设计语言编写程序代码,最后返回结果的过程。
2、Java 特性和优势
- 简单性 Java语言的语法与C语言和C++语言很接近
- 面向对象 封装,继承,多态
- 可移植性 使用字节码.clss文件
- 高性能
- 分布式
- 动态性
- 多线程 多线程机制使应用程序在同一时间并行执行多项任
- 安全性
- 健壮性 Java语言的强类型机制、异常处理、垃圾的自动收集等
注意:Java和C++的区别:
Java和C++都是面向对象的编程语言,都支持封装、继承、多态
Java不提供指针直接访问内存,程序内存更加安全
Java的类是单继承,C++的类是多重继承,但Java接口可以多重继承
Java有自动内存管理机制,不需要手动释放无用内存
3、Java 三大版本
JavaSE: 标准版(桌面程序,控制台开发......)JavaME: 嵌入式开发 (手机,小家电....)JavaEE: E企业级开发 (Web端,服务器开发....)
4、JDK JRE JVM
4.1、卸载jdk
- 删除
java安装目录 - 删除环境设置JAVA_HOME、Path
java-version 查看版本
4.2、安装jdk
注意:环境变量Path 下:
- 配置 %JAVA_HOME%\bin
- 配置 %JAVA_HOME%\
jre\bin
4.3、Jdk与Jre与Jvm的区别:
- Jdk包含一些Jre之外的一些东西,就是这些东西帮助我们编译java代码,还包括监控JVM的一些工具。
- JDK是开发人员使用的,其中包含Java开发工具 编译工具(javac.exe),打包工具(jar.exe) 也包含jre。
- jre:大部分都是C、C++语言编写的,是编译Java代码的基础类库。
- jre包含Java虚拟机和Java程序的核心类库等,核心类库:Java.lang包
4.4、什么是跨平台性?实现原理?
- 跨平台性:指Java语言编写的程序,经过一次编译,可以在多个系统平台上运行
- 原理:Java程序是通过Java虚拟机在系统平台上运行的,如果系统安装相应的Java虚拟机,则Java程序在该系统上运行。
5、第一个程序
Hello Word
- 随便新建一个文件夹,存放代码
- 新建一个
java文件- 文件后缀名为.java
- Hello.java
- 编写代码
/*语法*/
public class Hello{
public static void main (String[] args){
System.out.print("Hello,Word!");
}
}
- 编译 javac java文件,会生成一个class文件
javac Hello.java
- 运行class文件
java Hello
可能会遇到的情况:
- 每个单词的大小写不能出现问题,
Java是大小写敏感的 - 文件名和类名必须保证一致,并且首字母大写
- 符号必须使用英文
- java文件和class文件必须在同一个文件夹下
6、快捷键
psvm /*main方法*/
sout
ctrl+D 复制当前行到下一行
alt+enter 导包
100.for + enter 自动生成循环体
alt+ insert 构造器
ctrl+h
Ctrl+Alt+T 处理异常
7、英文
struct 结构体
operator [ˈɑpəˌreɪtər] 关键字
method 方法
8、内存分析
Java 内存
-
堆:
- 存放new的对象的数组
- 可以所有的线程共享,不会存放别的对象引用
-
栈:
- 存放基本变量类型(会包含这个基本类型的具体数值)
- 引用对象变量(会存放这个引用在堆里面的具体地址)
-
方法区:
- 可以被所有的线程共享
- 包含了所有的class和static变量
Java 基础
1、注释
// 单行注释
/*
多行注释
*/
/** JavaDos:文档注释*/
2、标识符
-
关键字
![]()
-
Java 所有的组成部分都需要名字。类名、变量名及方法名都被称为标识符。
/*语法*/
// Hello 类名
public class Hello{
// main 方法名
public static void main (String[] args){
// 变量名
String teacher = "秦疆";
System.out.print("Hello,Word!");
}
}
- 标识符注意点:

3、数据类型
3.1、强类型语言 java c c++
- 要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用
- 安全性高,速度慢
3.2、Java 的数据类型分为两大类
- 基本类型
- 数值类型
- 整数类型: Byte 1字节、short 2字节、int 4字节、long 8字节:后加"L"区分
- 拓展:进制 二进制0b 十进制 八进制0 十六进制0x 0~9 A~F
- byte 最大 127
- 浮点数类型:float 4字节后加"F"区分、 double 8字节
- 拓展:银行业务怎么表示? 钱
- float 有限 离散 舍入误差 大约
- 使用 BigDecimal 数学工具类
- 拓展:银行业务怎么表示? 钱
- 字符串类型:char 1字符 ,2字节, 一个汉字两字节
- 拓展:Java语言采用Unicode编码标准 编码 Unicode 2字节
- 转义字符:
- \t 制表符
- \n 换行
- 整数类型: Byte 1字节、short 2字节、int 4字节、long 8字节:后加"L"区分
- Boolean类型
- 1字节,只有true和false [fɔls]
- 拓展:boolean fiag = true;
- if(flag==true){}
- if(flag){}
- 数值类型
- 引用类型
- 类
- 接口
- 数组
3.3、类型转换
低---------------------------------------------->高
byte,short,char->int->long->float->double
- 运算中,不同类型的数据先转换同一类型,然后进行运算
输出类型比较高低
//强制转换 高---->低
int i = 128;
short b = (short)i;
System.out.println(b);
//自动转换 低------>高
int i = 0;
double d = i;
System.out.println(d);
注意:
/*
转换的时候可能存在内存溢出,或者精度问题!
*/
System.out.println((int)23.7); //23
System.out.println((int)-45.89f); //-45
4、变量
4.1、变量
-
变量是什么:就是可以变化的量!
-
Java是一种强类型语言,每个变量都必须声明其类型
-
Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域
type varName [=value] [{,varName[=value]}]; //数据类型 变量名 =值 ; 可以用逗号隔开来声明多个同类型变量 -
注意事项:
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型
- 变量名必须是合法的标识符
- 变量声明是一条完整的语句,因此每一个声明都比西以分号结束
4.2、变量作用域
- 类变量
- 实例变量 方法外部,类内部定义的变量
- 局部变量 类的方法中的变量
public class 类名{
//static 修饰符
static int allClicks=0; //类变量
//实例变量:从属于对象 默认值 0
// 布尔值:默认值false
//除了基本类型,其余默认值都是null
String str="hello word";
public void method(){ //方法
int i=0;//局部变量:必须声明和初始化
}
}
- 常量
final 常量名=值;
final double PI=3.14;
4.3、变量的命名规范
- 所有变量、方法、类名:见名知意
- 类成员变量:首字母小写和驼峰原则:monthSalary
- 局部变量:首字母小写和驼峰原则
- 常量:大写字母和下划线:MAX_VALUE
- 类名:首字母大写和驼峰原则:Man,GoodMan
- 方法名:首字母小写和驼峰原则:run(),runRun()
4.4、成员变量与局部变量的区别有哪些
变量:在程序执行的过程中,在某个范围内其值可以发生改变的量。从本质上讲,变量其实是内存
中的一小块区域
成员变量:方法外部,类内部定义的变量
局部变量:类的方法中的变量。
成员变量和局部变量的区别
作用域
成员变量:针对整个类有效。
局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)
存储位置
成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语
句结束后,就自动释放。
生命周期
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:当方法调用完,或者语句结束后,就自动释放。
初始值
成员变量:有默认初始值。
局部变量:没有默认初始值,使用前必须赋值。
5、运算符
注意:
| 运算类型 | 结果类型 | 描述 |
|---|---|---|
| long | long | |
| double | double | |
| 其他 | int | 不绝对,大部分 |
%:取余
++ -- :自增 自减
- a++ a=a+1; 先赋值,再自增
- ++a 先自增,再赋值
幂运算
Math 工具类
double pow = Math.pow(3,2);
System.out.println(pow); // 得9
&&、||、!与 &、|、^、~关系
| 逻辑运算符 | 关系式 | 描述 |
|---|---|---|
| && 逻辑与 | ab&&bc | 同true,得true 短路运算 |
| || 逻辑或 | ab||bc | 一个true,得true |
| ! | !(a==b) | 取反 |
| 位运算符 | 关系式 | 描述 |
|---|---|---|
| & 按位与 A= 0011 1100 B = 0000 1101 得 A&B=0000 1100 | A&B | 都为1,得1 |
| A|B= 0011 1101 | A|B | 都为0,得0 |
| 取反 ~B= 1111 0010 | ~B | 非A即B |
| 相同为0,不同为1 A^B= 0011 0001 | A^B | 异或运算 |
短路运算:&&左边表达式的值是false,则&&右边表达式不进行运算
**<<左移,>>右移 **
-
<< *2
-
用最有效率的方法计算 2 乘以 8
-
2 << 3(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次方)。
-
-
>>/2
字符串连接符 +
//String 字符串在前拼接
int a =10;
int b =20;
System.out.println(""+a+b);
1020
System.out.println(a+b+"");
30
? : 三元运算符
//x ? y : z
//如果x==true,则结果为y
== 和 equals 的区别是什么
== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数
据类型 == 比较的是值,引用数据类型 == 比较的是内存地址)
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过
“==”比较这两个对象。
情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象的内容相等;
若它们的内容相等,则返回 true (即,认为这两个对象相等)。
举个例子:
public class test1 {
public static void main(String[] args) {
String a = new String("ab"); // a 为一个引用
String b = new String("ab"); // b为另一个引用,对象的内容一样
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找
if (aa == bb) // true
System.out.println("aa==bb");
if (a == b) // false,非同一对象
System.out.println("a==b");
if (a.equals(b)) // true
System.out.println("aEQb");
if (42 == 42.0) { // true
System.out.println("true");
}
}
}
说明:
String中的equals方法是被重写过的,因为object的equals方法是比较的对象的内存地址,
而String的equals方法比较的是对象的值。
当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相
同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象。
6、JavaDoc



Java流程控制
1、Scanner 对象
定义:Scanner 类获取用户的输入
//基本语法
//创建Scanner对象
Scanner s = new Scanner(System.in); //System.in 输入
通过Scanner类的 next() 与 nextLine() 方法获取输入的字符串
通过hasNext() 与 hasNextLine() 判断是否还有输入的数据
public class Scannerdemo{
public ststic void main(String[] args){
//创建一个扫描对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接收:");
//判断用户有没有输入字符串
if(scanner.hasNext()){
Scanner str= scanner.next();
System.out.println("输出的内容为:"+str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要养好习惯用完就关闭掉
scanner.close();
}
}
next() 与 nextLine()
-
next():
- 一定要读取到有效字符后才可以结束输入。
- 对输入有效字符之前遇到的空白,next()方法会自动将其去掉。
- 只有输入有效字符后才将其后面输入的空白作为分割符或者结束符。
- next()不能得到带有空格的字符串。
-
nextLine():
- 以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符。
- 可以获得空白。
2、三大结构
1、顺序结构
- Java的基本结构就是顺序结构
- 顺序结构是最简单的算法结构
- 任何一个算法都离不开的一种基本算法结构
2、选择结构
2.1、if单选择结构
public class IfDemo1{
public static viod main(String[] args){
Scanner s = new Scanner(System.in);
System.out.println("输入内容:");
String str = s.nextLine();
if(str.equals("Hello")){
System.out.println(str);
}
System.out.println("End");
s.close();
}
}
2.2、if双选择结构
public class IfDemo2{
public static viod main(String[] args){
Scanner s = new Scanner(System.in);
System.out.println("输入成绩:");
int str = s.nextInt();
if(str>60){
System.out.println("及格");
}else{
System.out.println("不及格");
}
s.close();
}
}
2.3、if多选择结构
public class IfDemo3{
public static viod main(String[] args){
Scanner s = new Scanner(System.in);
/*
if 语句至多有一个else语句,else语句在所有的else if语句之后
if 语句可以有若干个else if 语句,它们必须在else 语句之前
一旦其中一个else if 语句检测为true ,其它的elseif 以及else 语句都将跳过执行。
*/
System.out.println("输入成绩:");
int str = s.nextInt();
if(str==100){
System.out.println("满分");
}else if(str<100&&str>=90){
System.out.println("A");
}else if(str<90&&str>=80){
System.out.println("B");
}else if(str<80&&str>=70){
System.out.println("C");
}else if(str<70&&str>=60){
System.out.println("D");
}else{
System.out.println("不及格");
}
s.close();
}
}
2.4、嵌套的if结构
if(布尔表达式1){
//如果布尔表达式1的值为true执行代码
if(布尔表达式2){
//如果布尔表达式2的值为true执行代码
}
}
2.5、Switch 多选择结构
/*
switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支
switch 语句中的变量类型可以是:
byte、short、int、char
switch 支持字符串String 类型
同时case标签必须为字符串常量或字面量
*/
char g = 'C';
Switch(g){ //布尔表达式g
case 'A':
System.out.println("优秀");
break;
case 'B':
System.out.println("良");
break;
default:
System.out.println("不及格");
}
//JDK7的新特性,表达式结果可以是字符串!
//字符串的本质还是数字
//反编译 java-----class(字节码文件)----反编译IDEA
String name = "狂神";
Switch(name){
case "秦疆":
System.out.println("秦疆");
break;
case "狂神":
System.out.println("狂神");
break;
default:
System.out.println("弄啥嘞");
}
3、循环结构
3.1、while 循环
/*
while 是最基本的循环
结构:while(布尔表达式){
循环内容
}
只要布尔表达式为true,循环就会一直执行下去 死循环
我们大多数情况是会让循环停止下来的
少部分情况需要循环一直执行,比如服务器的请求响应监听等
*/
int i=0;
while(i<100){
i++;
System.out.println(i);
}
//思考:1+2+3+...+100?
int i=0;
int sum=0;
while(i<=100){
sum = sum+i;
i++;
}
System.out.println(sum);
3.2、do.....while 循环
/*
do....while 循环至少执行一次
while与do... while区别:
while 不满足条件,则不能进入循环
while 先判断后执行,do..while是先执行后判断
Do...while总是保证循环体会至少被执行一次
*/
int i=0;
int sum=0;
do{
sum = sum+i;
i++;
}while(i<=100);
System.out.println(sum);
3.3、for 循环
/*
for 循环执行的次数在执行前就确定
for(初始化;布尔表达式;迭代更新){
//代码语句
}
*/
//死循环
for(;;){
}
//练习:计算0到100之间的奇数和偶数的和
int addSum =0;
int evenSum =0;
for(int i = 0;i<=100;i++){
if(i%2!=0){
addSum+=i;
}else{
evenSum+=i;
}
System.out.println("奇数和:"+addSum);
System.out.println("偶数和:"+evenSum);
}
//用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个
for(int i=0;i<=1000;i++){
if(i%5==0){
System.out.print(i+"\t");
}
if(i%(5*3)){
System.out.println();//换行
System.out.print("\n");//换行
}
//println 输出完会换行
//print 输出完不会换行
}
//打印九九乘法表
//第一步:打印第一列
for(int i=1;i<=9;i++){
System.out.println(1+"*"+i+"="+(1*i));
}
//第二步,把固定的1再用一个循环包起来
for(int j=1;j<=9;j++){
for(int i=1;i<=9;i++){
System.out.println(j+"*"+i+"="+(j*i));
}
}
//第三步,去掉重复项,i<=j
//第四步调整样式
for(int j=1;j<=9;j++){
for(int i=1;i<=j;i++){
System.out.print(j+"*"+i+"="+(j*i)+"\t");
}
System.out.println();//换行
}
3.4、增强for
/*
Java5 引入了一种主要用于数组或集合的增强型for循环
语法:
for(声明语句:表达式){
//代码句子
}
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。
其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
*/
int[] numbers={10,20,30,40,50}; 定义一个数组
//遍历数组的元素
for(int x:numbers){ //数组中元素依次输出
System.out.println(x);
}
4、break 和 continue
break在任何循环语句的主体部分,均可用break控制循环的流程。
break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)
continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
**关于goto关键字**保留字
goto关键字很早就在程序设计语言中出现。尽管goto仍是Java的一个保留字,但并未在语言中得到正式使用;Java没有goto。
然而,在break和continue这两个关键字的身上,我们仍然能看出一些goto的影子---带标签的break和continue.
“标签”是指后面跟一个冒号的标识符,例如: label:
对Java来说唯一用到标签的地方是在循环语句之前
而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另-个循环,
由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。
Java 方法
1、何谓方法?
Java是值传递
- System.out.println(),是什么?
- System ---类
- out ---输出对象
- println()----方法
Java 方法是语句的集合,它们在一起执行一个功能
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
- 一个方法只完成1个功能
//main方法
public static void main(String[] args){
//实际参数:实际调用传递给他的参数
int sum = add(1,2);
System.out.println(sum);
}
//public static 修饰符
//void 返回值类型(无返回值)
//加法方法
//形式参数,用来定义的作用
public static int add(int a,int b){
return a+b;
}
方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
返回值类型︰方法可能会返回值。returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType是关键字void。
方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
形式参数:在方法被调用时用于接收外界输入的数据。
实参:调用方法时实际传给方法的数据。
方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 参数名){
。。。
方法体
。。。
return 返回值;
}
//比大小
public static int max(int num1,int num2){
int result = 0;
if(num1==num2){
System.out.println("num1=num2");
return 0 ;//终止方法
}
if(num1>num2){
return result = num1;
}else{
return result = num2;
}
return result;
}
//调用方法:对象名.方法名(实参列表)
//Java支持两种调用方法的方式,根据方法是否返回值来选择
//当方法返回一个值的时候,方法调用通常被当作一个值
int larger = max(30,40);
//如果方法返回值是void,方法调用一定是一条语句
System.out.println("Hello Word");
值传递:指的是在方法调用时,传递的参数是按值的拷贝传递,传递的是值的拷贝,也就是说传递后就互不相关了。
引用传递:指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。
2、方法重载
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法的重载的规则:
方法名称必须相同。
参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
方法的返回类型可以相同也可以不相同。
仅仅返回类型不同不足以成为方法的重载。
实现理论:
方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
可变参数/不定项参数
- jdk1.5开始,Java支持传递同类型的可变参数给一个方法。
- 在方法声明中,在指定参数类型后加一个省略号(...)。
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。
- 任何普通的参数必须在它之前声明。
public static void main(String[] args){
//new一个对象
Demo04 demo04 = new Demo04();
//对象名.方法名()
demo04.test(1,2,3,4,5)//可以输入值,相同类型
}
public void test(int x,int...i){ //int...i 必须放到最后面
System.out.println(i[0]);//第0个
}
3、递归
递归就是:A方法调用A方法!就是自己调用自己
递归结构包括两个部分:
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
递归体:什么时候需要调用自身方法。
/*
阶层
1!1
2!2*1
3!3*2*1
*/
public static void main(String[] args){
System.out.println(f(5));
}
public static int f(int n){
if(n==1){
return 1;
}else{
return n*f(n-1);
}
}
Java 数组
1、什么是数组?
- 数组是相同类型数据的有序集合
- 数组描述的是相同类型的若干数据,按照一定的先后次序排列组合。
- 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。
2、数组声明创建
- 首先必须声明数组变量,才能在程序中使用数组。方法:
dataType[] arrayRefVar;//首选的方法
或
dataType arrayRefVar[];//效果相同
- Java语言使用new操作符来创建数组,语法如下:
//数组类型 数组变量名 数组大小
dataType[] arrayRefVar = new dataType[arraySize]
//这里面可以存放10个int类型的数字
int[] nums = new int[10];
//给数组元素赋值
nums[0] = 1;
nums[1] = 2;
//计算所有元数的和
int sum = 0;
//获取数组长度,arrays.length
for(int i=0; i<nums.length;i++){
sum+=nums[i];
}
System.out.println(sum);
- 数组元素是通过索引访问的,数组索引从0开始。
- 获取数组长度:
arrays.length
3、三种初始化
-
静态初始化
//创建+赋值 int [] a = {1,2,3}; Man[] mans = {new Man(1,1),new Man(2,2)} -
动态初始化
int [] a = new int[2]; a[0]=1; a[1]=2; -
数组的默认初始化
4、数组的特点
- 其长度是确定的数组一旦被创建,它的大小就是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。
- 数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
5、数组的使用
**for - Each **
//arrays.for快捷创建
//jdk 1.5 没有下标
for(int array:arrays){
System.out.println(array);
}
数组作方法入参
printArray(arrays);
//打印数组元素
public static viod printArray(int[] arrays){
for(int i=0; i<arrays.length;i++){
System.out.println(arrays[i]+"");
}
}
数组作返回值
int[] reverse = reverse(arrays);
printArray(reverse);
//反转数组
public static int[] reverse(int[] arrays){
int result = new int[arrays.length];
//反转的操作
for(int i =0;j=rssult.length;i<arrays.length;i++,j--){
result[j]=arrays[i];
}
return result;
}
6、二维数组(了解)
int a[][] = new int[2][5];
//[4][2]
int[][] array= {{1,2},{2,3},{3,4},{4,5}};
7、Arrays 类
数组的工具类java.util.Arrays
由手数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。
查看JDK帮助文档
Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象来调用(注意:是"不用”而不是"不能"")
具有以下常用功能:
- 给数组赋值:通过fill方法。
- 对数组排序:通过sort方法,按升序。
- 比较数组:通过equals方法比较数组中元素值是否相等。
- 查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。
8、冒泡排序
冒泡排序无疑是最为出名的排序算法之一,总共有八大排序!
冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层一次比较
//冒泡排序
//1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
//2.每一次比较,都会产生出一个最大,或者最小的数字
//3.下一轮则可以少一次排序
//4.依次循环,直到结束


9、稀疏数组(扩展)
数据结构
当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式是:
记录数组一共有几行几列,有多少个不同值
把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
Java 面向对象
1、面向过程&面向对象
-
面向过程思想
步骤清晰简单,第一步做什么,第二步做什么.…...
面对过程适合处理一些较为简单的问题 -
面向对象思想
物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
面向对象适合处理复杂的问题,适合处理需要多人协作的问题!对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
2、什么是面向对象
- 面向对象编程(OOP)
- 面向对象编程的本质就是:以类的方式组织代码,以对象的形式(封装)数据。
- 抽象
- 三大特性:
- 封装
- 继承
- 多态
- 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
- 从代码运行角度考虑是先有类后有对象。类是对象的模板。
3、回顾方法及加深
- 方法的定义
- 修饰符
- 返回类型
- break和return的区别:return 方法结束
- 方法名
- 参数列表 (参数类型,参数名)
- 异常抛出:throws IOException
- 方法的调用
- 静态方法 : 加static修饰,类名.方法名();调用
- 非静态方法 :
- 先实例化这个类new, new 类名().方法名();
- 对象类型 对象名 = 对象值;new 类名();
- 对象名.方法名();
- 形参和实参:类型要对应
- 值传递和引用传递
//值传递
public class Demo{
public static void main(String[] args){
int a=1;
Demo.change();
System.out.println(a);
}
//返回值为空
public static void change(int a){
int a =10;
}
}
//引用传递:对象:本质还是值传递
public class Demo{
public static void main(String[] args){
Perosn perosn = new Perosn();
System.out.println(perosn.name);// null
Demo.change(perosn);
System.out.println(perosn.name);//秦疆
}
public static void change(Perosn perosn){
perosn.name="秦疆";
}
class perosn{
String name;
}
}
4、类与对象的关系
- 类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。
- 动物、植物、手机、电脑
- Person类、Pet类、Car类 这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为。
- 对象是抽象概念的具体实例
5、创建与初始化对象
使用new关键字创建对象
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。
并且构造器有以下俩个特点:
1.必须和类的名字相同
2.必须没有返回类型,也不能写void
构造器
public class Person{
String name;//属性
//一个类即使什么都不写,它也会存在一个方法
//实例化初始值,使用new关键字,本质是在调用构造器方法
//显示的定义构造器
public Person(){};
//有参构造:一旦定义有参构造,无参构造必须显示定义
public Person(String name){
this.name =name;
}
}
启动类
public class Application{
public static void main(String[] args){
//new 实例化一个对象
Person person = new Person();//调用无参构造
Person person = new Person("kuangshen");//调用有参构造
System.out.println(person.name);
}
}
注意:一个项目只存在一个main方法,一个启动类
构造器:
1.和类名相同
2.没有返回值
作用:
1.new本质调用构造方法
2.初始化对象的值
注意点:定义有参构造后,如果想使用无参构造,显示的定义一个无参构造


Java 封装、继承、多态
1、封装
该露的露,该藏的藏
我们程序设计要追求“高内聚,低耦合”。
高内聚就是类的内部数据操作细节自己完成,把一个对象的属性私有化,不允许外部干涉;
低耦合:仅暴露少量的方法给外部使用。
封装(数据的隐藏)
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
记住这句话就够了:属性私有,get/set
作用:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统可维护增加了
Java 修饰符:
- public :对所有类可见,使用对象 类、接口、变量、方法
- default:对同一包可见,使用对象 类、接口、变量、方法 ,不使用任何修饰符
- private [ˈpraɪvət] : 对同一类可见,使用对象 变量、方法
- protected [prəˈtektəd]:对同一包的类和所有子类可见,使用对象 变量、方法
2、继承
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
extends的意思是“扩展”。子类是父类的扩展。
JAVA中类只有单继承,没有多继承!
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键extends来表示。
子类和父类之间,从意义上讲应该具有"is a"的关系.
继承:
让某个类型的对象获得另一个类型的对象的属性的方法。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
关于继承如下 3 点请记住:
子类拥有父类非 private 的属性和方法。
子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。
3、Super、this 关键字
3.1、this关键字的用法
this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。
this的用法在java中大体可以分为3种:
1.普通的直接引用,this相当于是指向当前对象本身。
2.形参与成员名字重名,用this来区分:
public Person(String name, int age) {
this.name = name;
this.age = age;
}
3.引用本类的构造函数
class Person{
private String name;
private int age;
public Person() {
}
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this(name);
this.age = age;
}
}
3.2、super关键字的用法
super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。
super也有三种用法:
1.普通的直接引用
与this类似,super相当于是指向当前对象的父类的引用,这样就可以用super.xxx来引用父类的成员。
2.子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区分
class Person{
protected String name;
public Person(String name) {
this.name = name;
}
}
class Student extends Person{
private String name;
public Student(String name, String name1) {
super(name);
this.name = name1;
}
public void getInfo(){
System.out.println(this.name); //Child
System.out.println(super.name); //Father
}
}
public class Test {
public static void main(String[] args) {
Student s1 = new Student("Father","Child");
s1.getInfo();
}
}
3.引用父类构造函数
super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。
this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。
3.3、this与super的区别
super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)
this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
super()和this()类似,区别是,super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
super()和this()均需放在构造方法内第一行。
尽管可以用this调用一个构造器,但却不能调用两个。
this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
this:它代表当前对象名,没有继承也可以使用
super:它引用当前对象的直接父类中的成员,只能在继承条件使用
this():是从本类中调用本类的其它构造方法、 super():是从子类内调用父类的构造方法
this()和super()都放在构造方法的第一行,均不可在static中使用
this和super不能同时出现在一个构造函数里
this的本质是指向本对象的指针,super是Java的一个关键字
4、重写、重载
-
重写Override
-
重载Overload
-
关系:
重载与重写都是实现多态的方式,重载是实现的是编译时的多态性,重写是实现的是运行时的多态性 重载:发生在同一类中,方法名相同,参数列表不同,与方法返回值和访问修饰符无关。 重写:发生在父子类中,方法名、参数列表必须相同。 抛出异常:范围可以被缩小,但不能扩大。Exception大 访问修饰符:范围可以扩大但不能缩小。 如果父类方法 ,访问修饰符为private,子类中就不是重写
5、多态
多态:对于同一个行为,不同的子类对象具有不同的表现形式。
多态存在的3个条件:
1)继承:继承关系
2)重写:方法需要重写
3)子类的引用赋给父类对象;父类的引用指向子类对象
多态是方法的多态,属性没有多态
6、static 关键字
6.1、static 存在的主要意义
- static [ˈstætɪk] 的主要意义是在于创建独立于具体对象的域变量或者方法。以致于即使没有创建对象,也能使用属性和调用方法!
- 用来形成静态代码块以优化程序性能。
- static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
- 很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
6.2、static的独特之处
1、被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享。
2、在该类被第一次加载的时候,就会去加载被static修饰的部分,而且只在类第一次使用时加载并进行初始化,注意这是第一次用就要初始化,后面根据需要是可以再次赋值的。
3、static变量值在类加载的时候分配空间,以后创建类对象的时候不会重新分配。赋值的话,是可以任意赋值的!
4、被static修饰的变量或者方法是优先于对象存在的,也就是说当一个类加载完毕之后,即便没有创建对象,也可以去访问。
6.3、static应用场景
因为static是被类的实例对象所共享,因此如果某个成员变量是被所有对象所共享的,那么这个成员变量就应该定义为静态变量。
因此比较常见的static应用场景有:
1、修饰成员变量
2、修饰成员方法
3、静态代码块
4、修饰类【只能修饰内部类也就是静态内部类】
5、静态导包
静态变量和实例变量区别
静态变量: 静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有一份,在类的加载过程中,JVM只为静态变量分配一次内存空间。
实例变量: 每次创建对象,都会为每个对象分配成员变量内存空间,实例变量是属于实例对象的,在内存中,创建几次对象,就有几份成员变量。
静态变量与普通变量区别
static变量也称作静态变量,
静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
还有一点就是static成员变量的初始化顺序按照定义的顺序进行初始化。
静态方法和实例方法有何不同?
静态方法和实例方法的区别主要体现在两个方面:
在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。
在一个静态方法内调用一个非静态成员为什么是非法的?
由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员。
7、接口
inference关键字
接口中的所有定义其实都是抽象的 public abstract
7.1、抽象类和接口的对比
抽象类是用来捕捉子类的通用特性的。接口是抽象方法的集合。
从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
相同点
- 接口和抽象类都不能实例化
- 都位于继承的顶端,用于被其他实现或继承
- 都包含抽象方法,其子类都必须覆写这些抽象方法
不同点
| 参数 | 抽象类 | 接口 |
|---|---|---|
| 声明 | 抽象类使用abstract关键字声明 | 接口使用interface关键字声明 |
| 实现 | 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现 | 子类使用implements关键字来实现接口。它需要提供接口中所有声明的方法的实现 |
| 构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
| 访问修饰符 | 抽象类中的方法可以是任意访问修饰符 | 接口方法默认修饰符是public,并且不允许定义为 private 或者protected |
| 多继承 | 个类最多只能继承一个抽象类 | 一个类可以实现多个接口 |
| 字段声明 | 抽象类的字段声明可以是任意的 | 接口的字段默认都是 static 和 final的 |
| 备注:Java8中接口中引入默认方法和静态方法,以此来减少抽象类和接口之间的差异。 |
接口和抽象类各有优缺点,在接口和抽象类的选择上,必须遵守这样一个原则:
行为模型应该总是通过接口而不是抽象类定义,所以通常是优先选用接口,尽量少用抽象类。
选择抽象类的时候通常是如下情况:需要定义子类的行为,又要为子类提供通用的功能。
普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类可以包含抽象方法。
抽象类不能直接实例化,普通类可以直接实例化。
8、内部类
定义:内部类就是在一个类的内部在定义一个类。
比如:A类中定义一个B类,B类相对A类就是内部类,A类相对B类就是外部类
成员内部类
//外部类
public class Outer{
private int id=10; //属性
public void out(){
System.out.println("这是外部类方法");
}
//内部类
public class Inner{
public void in(){
System.out.println("这是内部类方法");
}
//获得外部类的私有属性
public void getId{
System.out.println(id);
}
}
}
//启动类
public class Application{
public static void main(String[] args){
//new一个外部类
Outer outer = new Outer();
//通过这个外部类来实例化内部类
Outer.Inner inner = outer.new Inner();
}
}
静态内部类
局部内部类
//外部类
public class Outer{
public void method(){
//局部内部类
public class Inner{
public void in(){
System.out.println("这是局部内部类方法");
}
}
}
}
匿名内部类
public class Test{
public static void main(String[] args){
//没有名字初始化类,不用将实例保存到变量中
new Apple().eat();
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
Java 异常机制
1、什么是异常
Exception
要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:
检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
错误ERROR:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

在Exception分支中有一个重要的子类RuntimeException(运行时异常)
ArraylndexOutOfBoundsException(数组下标越界)
NullPointerException(空指针异常)
ArithmeticException(算术异常)
MissingResourceException(丢失资源)
ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。
这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;
Error和Exception的区别: Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。
Error
Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止;
还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。
2、异常处理机制
捕获异常Ctrl+Alt+T
int a = 1;
int b = 0;
try{//try监控区域
System.out.println(a/b);
}catch(ArithmeticExceptioncatch){// catch(想要捕获的异常类型)捕获异常
System.out.println("程序出现异常,变量b不能为0");
}finally{//处理善后工作,可以不要,假设IO,资源,关闭1
System.out.println("finally");
}
抛出异常
方法上抛出异常:throws
throw:主动抛出异常


浙公网安备 33010602011771号