day10-笔记

来源:互联网 发布:java企业项目开发实例 编辑:程序博客网 时间:2024/04/28 13:24

一.计算机基础

1.二进制

计算机中存储和传输数据都是以二进制形式.

二进制由0和1组成,逢二进一.

计算机中最小的单位bit, 1Byte等于8位, 1KB等于1024Byte.

2.机器语言和高级语言

机器语言就是由二进制组成的由计算机直接识别的语言.

高级语言是通过自然语言编程, 使用编译器编译成二进制, 由计算机识别.

3.Java的实现机制

使用自然语言编写源代码, 命名为.java文件.

使用编译器编译成.class字节码文件.

不同平台使用不同版本虚拟机, 都可以运行.class字节码文件, 实现跨平台.

4.搭建环境

JDK, 开发环境: java.exe, javac.exe,src.zip, rt.jar, jar.exe, javadoc.exe

JRE, 运行环境: java.exe, rt.jar

* 5.环境变量

path: 

通常我们想在任意路径下编译.java源代码, 那么就需要在任意路径下运行javac.exe. 

而我们在命令行中直接输入javac时, 是先在当前目录找javac.exe, 如果没有则在注册表找, 再没有就会到path环境变量配置的路径中找.

我们不可能在每个路径中都放置javac.exe, 也没有在注册表中配置, 所以可以将javac.exe所在目录添加到path环境变量中.

这样我们就可以在任意目录启动javac.exe了.

classpath:

虚拟机java.exe加载类的路径, 在JDK5.0之后不配置默认是当前目录".", 如果使用JDK1.4或之前的版本, 需要手动配置.

如果需要使用jar包中的类, 那么需要将jar包的绝对路径配置到classpath中.

配置环境变量的两种方式:

在命令行: set path=路径, 如果想引用以前的配置, 那么可以使用%变量名%, 这种方式只作用于当前窗口. 

在我的电脑 - 属性 - 高级 - 环境变量 - 找到对应的环境变量进行配置, 这种方式依次配置永久有效.

* 6.版本问题

为了保证java程序可以正常运行, 虚拟机java.exe的版本不能低于编译器javac.exe的版本.

查看版本的命令: 

java -version

javac -version

7.进制转换

十进制转二,八,十六进制:

将十进制数除以进制数, 取余数, 直到这个数等于0为止, 将所有余数反转, 就是对应的二,八,十六进制数.

将二,八,十六进制数转换为十进制:

将二,八,十六进制数编号, 编号从低位开始, 从0开始, 然后将每一位上的数乘以进制数的编号次方, 最后相加, 就得到十进制数.

8.负数

将十进制负数转换为二进制

原码: 将十进制数忽略符号转为二进制

反码: 将二进制每一位取反

补码: 将反码加1

9.码表

ASCII: 只包含英文字符, 每一个字符占1字节.

GB2312: 兼容ASCII, 包含常用中文. 英文占1个字节(正数), 中文占2个字节(负数).

GBK: 兼容GB2312, 对中文部分增容. 英文占1个字节(正数), 中文占2个字节, 第一个是负数, 第二个可正可负.

Unicode: 国际码表, 中文和英文都占2个. Java中就是使用的这种码表.

UTF-8: 国际码表, 英文占1个, 中文占3个.

二.Java编程基础

1.标识符

以任意组合的字母数字下划线和美元符号组成, 不能以数字开头. 不能使用关键字.

类名和变量名,方法名以驼峰式命名: 类名首字母大写, 变量名和方法名首字母小写, 后面每个单词首字母大写.

包名全小写.

2.常量

*******写在程序中不会改变的值***********

整型: 十进制, 八进制(0开头), 十六进制(0x开头), 占4字节.

长整型: 以L结尾, 占8字节.

单精度浮点数: 以F结尾, 占4字节.

双精度浮点数: 占8字节.

布尔: 1个字节. true和false.

字符: 占2个字节. "/"是转义字符, 将一些不可见或有特殊意义的字符转义. /r /n /t /b // /' /" /u0026 

字符串: 没有固定大小, 由零到多个字符组成.

空: null, 引用数据类型的默认值, 空, 代表不指向任何地址.

* 3.变量

a).基本数据类型

byte1字节

short2字节

int4字节

long8字节

float4字节

double8字节

boolean1字节

char2字节

b).引用数据类型

除了8种基本数据类型, 都是引用数据类型.

c).变量的使用

在使用一个变量之前, 必须对其进行初始化.

d).自动类型提升

byte, short, char在参与运算之后, 会自动提升为int.

e).强制类型转换

将一个占空间较大的值, 强制放入一个较小的空间, 有可能损失精度.

f).字符串相加

任何值和字符串相加都得字符串.

g).生命周期与作用域

生命周期从定义时开始, 到超出作用域结束.

作用域就是在定义变量的上一个开始大括号对应的范围内.

4.函数

a).函数的声明

返回值类型, 方法名, 参数列表

b).函数的重载

函数名相同, 参数列表不同, 和返回值类型无关.

5.运算符

a).算数运算符

整数除法的结果会向下取整.

在取模运算时模数的符号会忽略不计, 结果的正负只取决于被模数的正负.

i++是先取值再运算, ++i是先运算再取值.

b).比较运算符

注意==不要写成=

!= 不等于, 判断运算符左右两边的值是否不相等, 如果不等结果是true, 如果相等结果是false

instanceof, 判断运算符左边的对象是否是运算符右边的类型(或者子类)

c).逻辑运算符

&& 短路与 前半是false时短路, 不运行后半

|| 短路或 前半是true时短路, 不运行后半

d).位运算符

&将二进制的每一位进行与运算. 0或1&1都得自身, 一般用作取二进制数的某几位. 

|将二进制的每一位进行或运算.

^异或将二进制的每一位进行异或运算. 一个数异或任何数两次都得自身, 经常用于加密. 

>>右移将二进制的每一位右移. 移动前高位是0移后高位补0, 移动前高位是1, 移后补1. 右移几位, 就是除以2的几次方.

>>>无符号右移将二进制的每一位右移. 无论高位是0还是1, 移动后高位都补0.

<<将二进制的每一位左移. 低位补0. 左移几位, 就是乘以2的几次方.

6.程序的流程控制

a).选择结构

if...else if...else

switch...case: switch中可以接收的类型byte, short, char, int. 

二元运算符: 由?和:组成, ?前的表达式如果为true则取:前的值, 如果?前是false, 则取:后的值.

b).循环结构

while: 先判断while后的条件, 满足则执行循环体, 循环体执行结束后再判断, 直到不满足条件时推出.

do...while: 先执行循环体, 再判断while后的条件, 如果满足则运行, 不满足则退出.

for: 

for循环后的()中有3个语句. 

第一个在循环开始前运行, 且仅一次. 

第二个在每次循环开始之前运行, 如果满足则执行循环体, 不满足不运行. 

第三个在每次循环体执行结束之后运行.

c).break, continue, return

break: 结束循环

continue: 跳过一次循环

return: 结束方法

三.数组

1.什么是数组

数组是长度不可变, 类型一致的容器

2.定义数组

int[] arr = {1,2,3};

int[] arr = new int[3];

int[] arr = new int[]{1,2,3};

3.数组的遍历

使用数组的.length属性可以访问数组的长度.

知道数组长度之后, 可以通过循环来访问数组中的每一个元素.

4.使用数组时注意报错

越界, 数组的脚标(index)从0开始, 到length-1, 使用时如果超出这个范围, 会抛出ArrayIndexOutOfBoundsException

空指针, 如果数组的引用为空, 再使用数组时会抛出 NullPointerException

四.面向对象(上)

1.什么是对象

在程序中用对象来模拟现实社会中的事物.

2.什么是类

类是对象的抽象, 对象是类的实例.

3.创建对象

Person p = new Person();

栈内存中创建变量p

加载类 Person.class, 初始化静态变量, 运行静态代码块

堆内存中创建对象, 初始化成员变量

运行构造函数

给变量p赋值地址

4.对象的生命周期

从new关键字创建对象时开始

没有任何引用到达对象时结束

5.匿名对象

如果一个对象只使用一次, 就可以使用匿名对象, 不为其定义引用. 一般用于参数传递.

匿名对象的生命周期在使用过之后就结束了.

6.构造函数

构造函数是一种特殊的函数, 函数名和类名相同, 没有返回值类型.

一个对象在创建的时候, 一定会调用构造函数.

如果一个构造函数都不写, 默认会生成一个无参的构造函数.

如果写了有参的构造函数, 那么就不会生成无参的了, 在创建对象的时候, 如果不传入参数则会报错.

在构造函数的第一个语句, 可以使用this()调用其他构造函数.

7.this关键字

this用于方法内部, 是一个引用, 谁调用当前方法, this就引用谁.

a).访问类的成员时使用

b).引用对象本身

c).调用该类的构造函数

d).内部类中使用

8.参数传递

基本数据类型由于在变量中直接存储值, 传入方法之后改变其值, 改变的是方法中的形参, 调用处的变量不受影响.

引用数据类型由于在变量中存储的地址, 传入方法之后改变这个地址上的值, 是同一个地址, 所以调用处也受影响.

9.静态

变量: 在类加载后初始化, 被类的所有实例所共享, 可以使用 类名.变量名 形式访问.

方法: 在类加载后就可以使用, 可以使用 类名.方法名 形式访问.

代码块: 在类加载后执行. 静态代码块和静态变量初始化的顺序由代码从上到下的顺序执行.

内部类: 在类加载后就可以创建对象. 不需要创建外部类对象. 静态内部类中可以定义静态成员.

10.垃圾回收

在对象被销毁之前, 会自动调用finalize()方法, 这个方法继承于Object类.

垃圾对象在虚拟机中超过一定数量之后会自动销毁.

如果我们想手动销毁, 可以调用System.gc()方法, 通知虚拟机销毁垃圾对象.

11.单态设计模式

设计模式类似于棋谱, 公式. 在编程过程中经常遇到的一些问题, 由前人总结之后, 比较优良的解决方式.

单态设计模式就是某个类的实例在整个程序中只能出现一次.

编写方式:

先将构造函数私有化

在类内部定义一个成员变量, 创建一个对象.

定义一个公有的方法, 让别人可以获取这个对象

12.main语法

在Eclipse中给main方法传入参数

右键 - run as - open run dialog - arguments - program arguments

13.内部类

在类中定义的类就是内部类.

内部类对象需要先创建外部类对象才能创建.

内部类访问外部类的成员时要使用 外部类名.this.成员名

外部类不能直接访问内部类成员.

14.方法中的内部类

如果一个类只在某个方法中使用, 就可以定义在方法中.

方法中的内部类只能先声明, 再使用.

方法中的内部类如果方法方法中的局部变量, 那么这个变量必须声明为final.

15.静态内部类

静态内部类对象不创建外部类对象就可以直接创建.

静态内部类中可以声明静态成员, 而非静态内部类中不能有静态成员.

因为非静态内部类必须创建外部类对象才能使用, 而静态变量的本意是不创建任何对象就能使用, 他们矛盾. 

16.equals

比较两个对象的属性时使用equals方法, 在定义类的时候重写这个方法.

五.面向对象(下)

1.继承

定义一个类的时候, 使用extends关键字继承另外一个类, 就会继承其所有非私有成员.

Java只支持单继承, 不支持多继承, 可以多重继承. 

2.类型转换

a).类型自动提升

子类可以当做父类来用, 因为父类有的功能子类都有.

使用一个父类的变量, 引用子类对象.

这时使用父类变量调用该对象的方法, 调用的是子类的方法.

但是不能调用子类特有的方法.

b).强制类型转换

在使用父类变量引用子类对象时, 不能使用子类特有的方法. 

因为编译器在编译时有语法检查机制, 发现对象的引用是父类类型, 就会直接在父类中查找是否有该方法, 如果没有就会报错.

如果我们要使用这个父类变量引用的子类对象的特有方法, 那么就需要将其强制转换为子类类型.

在强制类型转换的时候, 为了确保不会在运行时出错, 一般需要使用instanceof判断一下要转的对象是否是对应的类型.

3.子类实例化

子类实例化时一定会调用父类的构造函数.

在一个构造函数中, 第一个语句要么是this(), 要么是super(), 如果没写this()或者super(), 默认是super().

4.覆盖父类方法

方法名相同, 参数列表相同, 返回值类型也相同.

如果想调用被覆盖的方法, 可以使用super.方法名

@Override可以检查覆盖是否成功.

5.多态

以不变应万变:

将方法的形参定义成父类类型, 那么所有子类对象都可以传入. 这么做方法不变, 传入不同参数, 运行结果不同.

向后兼容

在定义类的时候不用考虑以后的子类是怎么实现的, 通过父类中的方法调用, 传入的时候传子类对象, 就可以调用到子类对象的方法. 先写的代码可以调用后写的代码.

6.final

a).类, 不能被继承

b).方法, 不能被覆盖

c).变量, 只能赋值一次. 注意基本数据类型和引用数据类型的区别.

7.组合设计模式

在定义一个类的时候, 发现需要另一个类的方法时使用.

在类中定义一个指定类的成员变量.

通过构造函数组合进来一个指定类的对象.

在需要使用这个类的方法的地方, 通过成员变量调用其方法.

组合的优点:

不占用继承的位置

有的类和类之间没有逻辑上的父子关系, 不适合用继承

8.抽象类和接口

抽象类是abstract class, 接口是interface

抽象类中可以有不抽象方法, 接口中的方法都是抽象的

抽象类使用extends继承, 接口使用implements实现

抽象类中的成员的修饰符没有特殊之处, 接口中的方法默认由public abstract修饰, 接口中的属性默认由public static final修饰

一个类只能继承一个抽象类, 一个类可以实现多个接口

9.异常

异常可以简单分为三类: 

运行时异常: RuntimeException, 这些异常在程序中经常出现, 不对其进行处理编译时不会报错. 如果运行时抛出此类异常, 会交给默认处理程序处理, 会打印出异常信息.

编译时异常: Exception中除了RuntimeException的部分, 这类异常需要在程序中对其进行处理, 如不处理编译时会报错.

错误: Error, 严重的错误, 一般由虚拟机抛出, 程序中无法对其进行处理.

异常的处理:

声明抛出:

使用throws关键字声明抛出. 如果main方法中抛出异常, 则会交给默认处理程序, 打印异常信息.

捕获:

使用try...catch代码块捕获, 如果try中的代码抛出了异常, 就会运行catch中的代码.

10.包

package语句必须放在代码的第一条语句.

有包的类不能访问无包的类, 无包的类可以访问有包的类. 所以我们以后写类时要写上包, 别人可以在其他包中访问.

导入包时尽量导入全限定名, 这样不论当前包中是否有同名类, 都会找导入的类. 如果使用*的形式, 会先在当前包找, 如果当前包中有则会使用当前包的.

11.jar

jar是一种压缩格式, 通常我们会将class文件压缩成一个jar包

jar cvf jar包名 class文件名/文件夹名

如果要使用一个jar包中的类, 那么需要将jar包的绝对路径配置到classpath中 

思考题:

海滩上有一堆桃子, 五个猴子来分.

第一只猴子来到海滩将桃子分为五份, 发现多了一个, 扔到了海里, 拿走了一份.

第二只猴子来到海滩和第一只一样, 将剩下的桃子又分为5份, 发现多了一个, 扔到了海里, 拿走了一份.

...

...

...

后面几只猴子都是这样做的. 问: 海滩上最初有多少个桃子?

答案:

public class PeachTest {

public static void main(String[] args) throws InterruptedException {

outer: for (int i = 0;; i++) { // 定义一个无限循环, i每次增加1

int quantity = i; // 定义变量记住这个数

for (int j = 0; j < 5; j++) {

if ((quantity - 1) % 5 == 0) // 如果这个总数可以满足扔掉一个平均分成5份

quantity = (quantity - 1) / 5 * 4; // 那么就扔掉一个, 分成5份, 拿走一份

else

continue outer; // 如果不满足扔掉一个平均分成5份, 那么这个数就不用再计算了, 直接跳入下一个数

}

System.out.println(i); // 如果循环5次之后都没有跳过, 那说明这个i可以满足分5次.

break;

// Thread.sleep(1000);

}

}

 

}

 

/*

  312131206242496

  249624954991996

  199619953991596

  159615953191276

  127612752551020

*/

原创粉丝点击