#java 基础
##java运行机制和jvm
java 不是纯粹的编译语言也不是纯粹的解释语言
编译 生吃.class文件 不是特定平台的机械码 平台无关的字节码
解释
jvm负责执行字节码 jvm是一个抽象的计算器 有 指令集,寄存器,类文件格式,栈,垃圾回收, 储存区。(实现了java与平台无关性)
jdk java SE Development KIt java标准版开发包
jre java Runtine Environment java运行环境
jvm在jre里面
javaEE中开发就是SDK Software Development Kit
bin JDK的各种命令工具
db 安装java DB的路径
lib jdk工具命令实际执行程序
src。zip源代码
path 设置
window系统通过path找命令。依次找path中看是否有命令,有就运行没有就不是内部或外部命令。path值就是路径(不区分大小写)
用户变量 系统变量 实质是对于用户和整个系统的区别
javac .java
java 类名
.class 文件的名字是由里面的类名决定的。
java区分大小写
不设置classpath 会在当前路径系寻找
classpath 环境变零的配置 1.5 版本以上的可以不用配置。
1.4 版本以前的要加上.
.%JAVA_HOME%\lib\dt.har;.%JAVA_HOME%\lib\tool.jar %JAVA_HOME% JDK安装目录
###JAVA程序的基本规则
class Test{}
是一个类可以编译但是没有办法运行找不到main方法 主函数
如需某个类被解释器直接执行,类必须有main方法,而且main方法必须被
pubiic static void main(String[] args){}
###命名规则 源文件后缀必循是.java.通常原文件名任意但是有public 修饰的名字一定和类名一样(一个源文件中只有一个public类 别的类只要不是public 有几个都行)。
通常 1 java源文件只定义一个类
2 源文件名与public 类相同
###垃圾回收
jre和负责回收那些不实用的内存,这种机制被称为垃圾回收机制(Garbage Collection GC) 一般是CPU空闲或是内村不足时 回收,程序员无法精确控制垃圾回收的时间和顺序。
java虚拟机中存放着java运行时的对象在对堆内存,垃圾回收是一种动态储存管理技术。 垃圾回收还乐意处理碎片
垃圾回收 做的事 1 发现无用对象2回收对象所占的空间。
对象射程null 可以更好的提醒垃圾回收机制。
Runtime对象的gc()和System.gc()提醒垃圾回收。但是不能精确回收。
精确性 1 精确的标记活着的对象2 精确对象之间的引用关系。
编程上不需要的对象不在引用。
#面向对象
面向对象的单个基本特征 1 封装 2 集成 3 多态
OOA面向对象分析 OOD面向对象设计OOP面向对象编程
UML统一建模语言来记录
结构化开发 面向对象开发
##程序的三种基本结构 (GOTO关键字可以控制流程任意跳转 java 中不用太随意了造成难以读取)
任何简单或是复杂的算法都是由三种算法构成 1顺序机构 2 选择结构 3 循环结构
1,顺序结构
按源代码排列顺序来执行的。
程序只能从一个入口进一个入口处按着顺序一个一个的来走。
2选择结构
根据某个特定条件来选择分支,选择结构有单选,双选,多选。
双选是典型的选择结构。
true
条件 b
false
条件 false b
true c
多选
条件 true s1 b
false
条件 true s2
false
条件 true S3
无论哪个分支走到最后都是出口b
循环结构
反复执行某个或是某些操作。知道条件为真或是为假时。停止。
当循环 先判断 条件为正真时执行
for
直到循环 从入口到 条件 true是在继续循环。 至少执行一次 do while
###面型对象设计简介
基本思想 是 类 对象 继承 封装 消息 等用对象类来进行软件设计。并在系统构造中近可能的运用人类思维来设计。强调直接以现实中的食物来思考。
本质特点然后抽象出来。抽象舍去那些我们不用的特点。
面向对象最小的单元就是对象也就是程序中的类。
类代表了显示生活中的有某种特征的一类事物。这些食物往往有一些内部的状态数据。只有的是程序员关心的数据。面向对象语言使用类来封装数据。
成员变量 (状态数据)+方法(行为)=类的定义。
粒度 指的是最小单元。
主谓宾 类.do(参数)
##面向对象的基本特征
封装 实现的细节隐藏起来,只把方法暴漏出来。 继承 单继承 多继承 java单继承 继承父类的属性和方法。
多态是指子类可以直接赋值给父类变量。还能表现出子类行为。
对象 面向对象的基本概念。他的基本特点 表示唯一 分类性 多态性 封装性 模块独立性好。
类是有共同属性、共通方法的一类对象。类是对象的抽象。而对象就是类的实体。类是程序的最小单元。类把各种细节封装起来。并且公共方法暴露改类。对外提供功能。 提高类的内聚,降低耦合。
面向对象方法中。类之间共享属性和方法的机制成为继承。
基于对象的
javascrip 就是基于对象的。也是用了对象但是唯有办法基于想在的对象产生新的对象。也就是说没有办法继承。
多态更是基于继承的。没有继承跟不用说多态了。
##UML 统一建模语言
记录面熟OOD OOA的表达法
UNL图可以分为静态的或是动态的(大体上分为)
13中UML图。
常用的 用例图 类图 组件图 部署图 顺序图 活动图 状态图
1 用类图
用例 椭圆 角色 Actor
2 类图
类的静态内部结构。 还有就是类关系。
关联 整合 组合
关联关系 客观世界中两个事物往往存在千丝万缕的关系。抽象到软件中来。类就一定有索关联。关联是具有方向性的。一个类单方面的访问一个类就是单向关联。互相访问就是双向关联。一个对象访问关联对象的数目成为多重性。 关联用一条实线表示 到箭头的表示单向关联。、
聚合关系 多个对象做成一个整体 空的菱形整体布冯箭头就是对象
组合关系 腿和人 对象是箭头 实心菱形就是整体
多重性 多个
泛化 与继承同一个概念。都是之子类是一个特殊的父类。
还有一种特殊的继承关系 类实现接口。
依赖
一个类改动会导致另一个类改动就是依赖关系。带尖头的虚线表示
常见 1改动的类将消息发给另一个类
2 改动的类以另一个类作为数据部分
3给动的类以另一个类作为操作参数。
通常以来是单向的。尤其是当数据表现和数据模型分开设计时。
3组件图
对大型应用程序而言。不是单独一个类或是一组类能完成的通常会出现一个或多个可部署组件。 对于java而言可服用的组件通常会打包成jar或是War样式。
组件图提供系统的物理视图。显示系统中软件对其他组件的依赖关系。。做见图可以在非常高的粒度显示。也可以在组件包层次显示。
组件图通常包含组件 接口 和port等园元。椭圆接口 插销组件。组件边上的小矩形代表port
接口对他提供服务规范。通常有两种
1 用一条条实现链接到组件外边的圆圈表示。
2使用位于组件内部的圆圈表示。 依赖于某一个接口 组件依赖于某一个借口用一个半圆的直线表示。
4部署图
然间不是单机的变成跨国家,跨地区的分布式软件。 部署图用来描述软件部署到不同的硬件环境中。 不同的做件在何处物理运行以及他们讲如何通信。
用物理结构建模 所以就可以很好的安装。
组件图中所使用的符号元素,还增加节点的概念。节点是各种计算资源通用名称。包括处理器和设备。处理器是能够执行程序的硬件构成。设备是不具有计算能力的硬件构成。打印机。UML三维立方体来表示节点。名称位于立方体的顶部。
5 顺序图 描述对象之间的交互(顺序图 通信图都称为交互图。 )重点在于描述消息极其时间顺序。
显示具体用用例的详细流程。 并且显示不同对象之间的调用关系。可以很详细的显示不同对象的不同调用。
顺序图有两个维度, 1 垂直唯独 表示放生的时间 显示消息/调用与序列。水平维度 显示消息发送对象实例。关键是对象之间的消息。框中的类名称 和实现类用冒号或空格来分隔。传递消息带尖头的实线来表示。消息或方法的名称放在实线上面。返回值指向发起对象的虚线变大返回值写在上面。
消息穿梭时序图尽量把发送者与接收着相邻拜访。避免跨越对象。
对象激活期不是其存在的时间而是其在cpu执行的时间。时序图绘制时激活期要准确。(表现协作关系 不善于表现精确定义)
6 活动图
活动图和状态机制图都称为演化图。
用于描述用例内部的方法 和流程。除去活动图中并行互动描述就成了流式图
状态图 描述一个对象生命周期中不同的状态。并会描写刺激对象改变的事件。以及对象状态改变行为。
状态 对象响应事件后不同状态。目前的计算机都基于状态中的稳定态。对象状态越多与复杂,用的都是状态有限的。
事件 来自外界对象的刺激。
动作 针对所发事件的处理
活动 动作激发后系统行为
条件 事件发生所需具备的条件。
激发对象改变的事件 1 内部时间一个对象方法调用另一个 2外部事件 鼠标键盘
活动图 主要描述过程原理 业务逻辑以及工作流程。圆角矩形代表活动 带箭头的是事件。支持并发描述
和传统的流程图不同可以有多个并行分支分出多条并行活动
7状态机制图
对象所处不同状态和该类状态转换信息。 有三个或更多状态才可以用状态机制图
五元素
初始状态 实心圆 状态之间的转换 带尖头线段来描绘 状态 圆角矩形来描绘 判断点 空心圆来描绘
一个或多个中指点 内有实心的园来描绘。
Hibernate 的状态 瞬态 持久态 托管 来相互转化
java 面向对象特征
(封装 集成 多态)
除8个基本数据类型外其他多是对象。
定义成员变量 来描述对象状态 操作改变状态的 方法来描述这种操作 对象的行为
对象实现数据和操作的结合
对象有唯一的标识符来引用他 当一个对象没了引用就成了垃圾 java不直接访问对象而是用对象的引用来访问对象。
类和对象
对象抽象就是类 类的具体实现就是对象
class 中成员对象描述数据 方法描述对象的特征。
一般特殊关系 继承关系 a 是 一种b
整体 部分关系 组装结构 有一个
new 创造对象 每个对象有不同的成员 可以创造多个对象。
##数据类型和运算
java 强制类型语言
强制类型语言 1变量必须先声明在使用2 指定类型的变量只能接受类型与其匹配的值。
强制类型语言可以在编译时发现源代码错误。
基本数据类型 数值型 和布尔型 数值型有 整数 字符 浮点
运算符 位运算符 比较运算符 逻辑运算符
注释 单行注释//
多行注释 /* */
文档注释/** */
文档注释 javadoc 程序接口 API来编程
JDK不仅仅有API文件还有其他的东西。
太多的类记不住就要看看API文档了解一下各个部分
@author: java程序的作者
@version: 版本号 @deprecated 不推荐用法
@ param: 参数说明
@ see: 参见交叉参考定义
@excepation: 抛出异常的类型
@throws: 抛出异常
记得加冒号
##标识符和关键字
1分隔符
; () {} [] .
;语句的结尾 ()优先运算 参数 {}语句块 []数组 .对象.属性 或方法 调用的准确。 空格没有意义 自由个是语言被忽略。但是记住不能再类名中加空格。
2 标识符规则 java 长度任意 数字 字谜 下划线 $ 中文字符和日文字符
java 支持Unicode字符集 并且区分大小写
1 不能以数字开头
2不能用关键字或是保留字
3不能有空格
4只能是$不能是@ 等等
java关键字 (keyword)
java中的关键字都是小写的。 final修饰的常量容易使大写的
50个关键字
abstact continue for new switch assert default if package synchronized boolean do goto (没用留着的) private this break double implements(实现) protected throw byte else import public throws case enum instanceof return transient (java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是,用transient关键字标记的成员变量不参与序列化过程) catch extends int short try char final interface static void class finally long strictfp(strictfp 关键字可应用于类、接口或方法。使用 strictfp 关键字声明一个方法时,该方法中所有的float和double表达式都严格遵守FP-strict的限制,符合IEEE-754规范。当对一个类或接口使用 strictfp 关键字时,该类中的所有代码,包括嵌套类型中的初始设定值和代码,都将严格地进行计算。严格约束意味着所有表达式的结果都必须是 IEEE 754 算法对操作数预期的结果,以单精度和双精度格式表示。) volatile(就像大家更熟悉的const一样,volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果不加入volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。)
const (没用) float native(native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。) super("super"。它和"this"类似,但是也有不同的地方。
1。表示调用父类的构造函数。也是一个特殊语法,不是变量,没有什么类型。
2。可以在一个类的非static成员内部使用。比如super.method()。
但是,注意,这个super.method()只是长得跟some_var.method()一样,一个语法糖而已。实质上,"super"根本不是一个变量。
) while
goto const 保留没有用 三个直接量 (literal);true false null
程序的本质就是对内存中的数据进行修改 变量就是访问内存中数据的机制。每个变量都占一个内存。(变量相当于一个有名的容器)
变量分为 成员变量 和局部变量 无论哪种变量都要指定他的类型 和名字
可以指定也可以不指定变量值。
java语言支持的类型基本类型和引用类型。
基本类型包括 boolean 和数值类型 (整数类型和浮点数类型)
引用类型包括。(类 接口 数组 null)
所谓的引用类型就是对对象的一种引用。对象包括实例和数组两种。引用类型就是一个指针。java中没有指针这个说法。
空类型null 。null没有对象 空引用就是null null可以变成任意的类型。
基本数据类型
byte 1 8 bit(-128--127) short 2 byte(2万) int 4 byte(20亿) long 8 byte
char 2 byte float 4byte double 8byte
java默认的是 int double
byte short 复制不超就是 超了的话不会组为long处理 希望变成long后面加l 可以讲较小的数值给long自动类型转换。
八进制 0 十六进制0X 以0b开头的是2进制
负数存的是补码开头是1 补码先减一 在取反就可以读值了。 数据运算以后存在截取。注意补码
字符型
16位Unicode编码方式。ASCII最原始的码表 后面又进行了添加。
字符型值有三种表现形式。
1 指定字符 0 9 A
2转义字符 \n \t
3Unicode值来表示字符类型 \uXXXX xxxx表示16进制整数。
转义字符
\b 退格
\n 换行
\r 回车
\t 制表
\' 单引号
\\ 反斜线
char 0-65535 底层不存的也是数字 2byte
char 也可以进行加减乘除运算。
java中没有字符串基本类型 通过String类来表示字符串类型字符串由多个字符组成要用双引号引起来。
char 单引号 String 双引号 java中单引号双引号 反斜线 都有特别的意思。在输入时记得转义。
c:\\codes
浮点数 不是精确地数字。
float 1 位符号 8位指数 23位位数 4字节 32位
double 1位富豪 11位指数 52位尾数。 8字节 64位
java浮点数表示 1 十进制 有小数点 否则就成了int 2 科学计数法表示。
只有浮点数才可以用科学记数法表示。 float 点数是记得要加F
java提供了3种特殊的浮点数 1 正无穷 正数/0 POSITIVE_INFINITY 2负无穷 负数/0 NEGATIVE_INFINITY 3非数NaN 负数开方(都在float 和double 类里面有)
必须是浮点数/0才会有无穷
整数/0会出异常 ArithmeticExcepation:/by zero
##数值中使用下划线
下划线风格 可以是整数也可以是浮点数 用来更好地表明位数。
0b1111_0111_0000_1000
###布尔型
在JAVA中之呢个是真或假 true or false 不能是0或1 (c)
java指有制定 boolean所占的空间 所以一般都是计算机分配内存时的最小单元 byte 8 bit
字符串true不会直接转换成boolean类型。如果boolean类型和字符串链接运算就会变成自符串。
boolean a=true;
boolean类型的值或变量主要时进行流程控制。java中流程控制有
if
while
do
for
和三木(三元)运算。
##基本类型转换
自动类型转换 强制类型转换
数值类型变量 当把表数小的赋值给表述大的 都进行类型提升。
char
int long float double
byte short
从左向右自动类型提升
任何基本类型和字符串连接时都会成为字符串。(字符串是引用类型)
public class Test{
String a="5";//因为String不能赋值成String a = 5;不能把整数赋值给字符串。
system.out.println("Hello"+7+8);//hello78
system.out.println(7+8+"hello");15hello
}
###强制类型转换
从有向左边 缩小转换(Narrow Conversion)强制类型转换运算符();
大转小先截取在转换。数字片段。(非常容易引起数字丢失)
注意 float a=0.5;是错的 double是默认的 要提示系统
正常情况下字符串是不能转化成基本类型的。只有用基本类型的封装类才可以进行转化。
boolean Boolean
byte Byte
short Short
int Integer (注意)
long Long
float FLoat
double Double
String a="45";
int value = integer.praseInt(a);
praseXxx(String str)的方法。
表达式类型自动提升。
一个算数表达式包含多个基本类型的值。表达式的数据类型就会自动提升。表达式中的最高。按排序表提升。
a=97 char ASCII
表达式的类型会和最高的一至。int/int 最后也是整数。不会有类型转换。直接舍去。
直接量
通过元代码直接给出的值。
直接量的类型。
三种 基本类型 字符串类型 null
int (2进制10进制 8进制 16进制) long float double
String char boolean null
8种直接类型变量
null类型的值只有null
指的是一种一个引用对象还没有指向任何地址。地址为空 没有指向对象。
####直接量的赋值
String 不能给其他值赋值 null 直接给任何引用变量, boolean只能赋值给boolean
String类型的直接量负值时。会把值赋值到常量池。(constant pool)缓存该数字的常量。后面部分如果还要用到字符串的直接量时。java会直接使用常量池中的直接量。
String不可变量创造出来就不会改变
常量池(constant pool) 编译期被确定的。并保存在以编译的.class文件中。
==常量的比较。引用类型是相对的地址值。
##运算符
特殊的符号
算术运算符
赋值运算符
比较运算符
逻辑运算符
位运算符
类型运算符
算术运算符 7个
+ - * / % (余数不一定是整数 整数取模整数 浮点数可能有小数 是一个整数商后面余下的数字)
++ -- n++ n-- 哪个在前面先运算哪个。(只能用于操作变量 直接亮本身不行)
更为复杂的运算 就要用 jva.lang.Math 中的方法了。
double a=Math.pow(a,5);a的5次方
double c=Math.aqrt(a);a的平方。
double d=Math.random();
赋值运算符 =
将变量作为容器 而赋值就是将变量装入的过程。
赋值表达式是有值得 值就是 表达式右边的值
3位运算符
7个
& | ~ ^ << >> >>>(无符号右移)
2位中 ~就是取相反 ^相同为0 不同为1
<< >>> >>(运算更快 更简单)
位移就是 向右正数补零 负数补一 左移补0
无符号右移 用零补。
对于移位运算
低于int 的先提升为int 32位
int 类型的 a>>b 如b>>32 则现对32取余余才是位移的位数。
long类型的 a>>b 先b对64 取余 然后位移。
(2进制只有有效位数不丢失 就是相应的2 的倍数) 位移运算不会改变操作数本身。只会得到一个新的结果。
拓展后的赋值运算符。
+=
-+
*=
/=
%=
&=
|=
^=
<<=
>>=
>>>=
提高性能并且更加健壮。(结果一样但是机制不同)
比较运算符
> < <= >= ==(引用类型只用都指向一个对象才会相同 地址哈希码) !=
只要是数值类型 只要值不同都会返回true (int char byte short float double)
包装类
逻辑运算符 6 个
&& & || | ! ^ (短路只要可以判断了 就不会再进行下去)
三目运算
(expression) ? if-true-statement:if-not-statement
if slse
简写法
String a = 5>3? "5大于3":"5小于 3";
System.out.println(a);
区别 if后面可以有多个语句块 但是三元运算只能有一个。
三元运算可以嵌套
(a>b? "a大于b":(a<b?"a小于b":"a等于b"))
运算符的结合和优先级
除了 单目运算 赋值运算 三目运算 都是从左往右的 (良好的规范就行不要看千奇百怪的问题)
优先级
不要把表达式写的过于复杂 复杂分几步来写 不要用运算符的优先级运行用()来表示
分隔符 []{}().,;
单目运算 ++ -- ~(位运算符 非) !
强制类型转化运算符(type)
乘法除法求余 */%
加法 减法 + -
位移运算符 << >> >>>
关系运算符 < > <= >= instanceof(类和继承有关)
等价运算符 == !=
按位与 &
按位异或 ^
按位或 |
条件与 &&
条件 ||
三目运算 ? :
赋值 = += -= *= /= ^= %= <<= >>= >>>=
自己写的时候 不要把表达式写的过于复杂 复读偶很重要 包要以来运算符的优先级 要自己加()
#流程控制与数组
流程控制结构 分支结构 实现根据条件选择的实现某一段代码 if switch
循环结构 实现根据循环重复的代码 while da while for
JDK 1.5 foreach 循环
break continue 来控制循环结构
##顺序结构
从上到下中间没有任何跳转 和判断 main方法 前面的先执行后面的后执行
##分支结构
if 条件语句(布尔表达式或是布尔值来判断)
if(logic expression){
statement
}
if(){}slse{} 写的时候不要偷懒
一个代码块通常当作一个整体来实行。除非遇到了(return break continue 关键字 或是异常) 这个代码块 也称作条件执行体
注意理解 如果if()只有一个语句则是可以省略大括号的。自己不用
; 空语句 后面分支会乱。
空语言也可以作为条件执行体。
多条语句知兴替省略了花括号则会发生编译错误。 else找不到if
编译错误
if爱出逻辑错误 注意 范围小的写在上面 。不然后面就不执行了
##java1.7 后增强的 switch 语句
switch后面可以接多个case标签。 case后面的数据只能是 byte short char int 四种整型类型 枚举 和 java.lang.String 类型(不能是其他的如StringBuffer StringBulider ) 不能使boolean型。
switch(expression){
case conditional :{
statement (s)
break;
}
case conditional :{
statement(s)
break;
}
default :{
statement ()
}
}
分支结构现对 expression求职 然后再依次匹配conditional 都不匹配在执行default
可以省略花括号 default 看似没有条件但是隐含条件就是与前面的都不匹配。
语句块中的break十分重要 去掉会一直执行下去
和执行流程有关系。当执行完表达式 回去匹配 到匹配完成后就会一直执行下去,不再进行匹配。遇到break才会停止。
##循环结构
满足循环条件的情况下 一直执行某一段代码 这段代码被称为循环体。
循环语句 4部分
初始化语句 init_statement 一条或多条在循环语句之前
循环条件 test_expression noolean表达式 角点股市否执行循环
循环体 body-statement 重复执行 只有一句花括号可以省略
迭代语句 iteration_statenment 一次循环执行结束后,对循环条件求值之前执行,通常用于控制循环条件中的变量,是循环在合适的时候结束。
while 循环 语句
while 循环语句格式
[init_statement]
while(test_expression){
statement;
[iteration_statement]
}
执行顺序 每次执行之前都要对test_expression 求值。true 运行循环体部分,迭代语句总在循环体之后执行,因此只有在循环体执行完才会执行迭代语句。 循环也是有条件的 当test_exprssion 一开始为false时循环部分将永远不会执行。
如果省略了循环体的花括号,那么while循环条件仅控制到第一个分号处
。
使用while时一定要确保循环条件有变成false的时候。否则就成了死循环。
while后面直接一个;号空语句变成了死循环。
###do while 循环语句。
while 先判断为真的时候在执行。do while 先执行在判断,真的时候循环。
[init_statement]
do{
statement;
[iteration_statement]
}while(test_expression);
与while 不同的是 do while 后面有一个分号。来表示循环结束。
## for 循环
for 循环是更加简洁的循环语句 大部分情况下 for 代替 while do while for 循环。
for([init_statement];[test_expression];[iteration_statement]){
statement
}
执行顺序 先执行初始化语句 初始化语句只在执行前执行一次,每次执行循环体之前先计算test_expression 如果条件为true则执行循环体,循环体执行之后执行迭代语句。循环条件总比循环体多执行一次 最后一次是 false
值得提出的是 for循环迭代语句并没有与循环体放在一起,当执行循环体遇到continue是迭代语句也会被执行。 while dowhile 迭代语句和循环体在一起所以遇到continue就不会执行了
和前面一样 循环体只有一个时可以省略花括号。
for初始化可以使多个,条件也可以是一个包含逻辑运算符的表达式。
for(int count = 0,s =6, a= 7;b<10&&s<9&&q<1;count++){
System.out.println("大家好");
}
建议不要再循环体内修改循环变量(也叫循环计数器)的值。否可可能会出错。
将以重新定义一个临时变量,先将循环的值,赋值给临时变量,然后对临时变量进行修改。
for循环圆括号中只有两个;;是必学的其他都可以省略。 默认条件weitrue 进入死循环。
也可以把初始化并一再for循环之外。
如果 for(;count;){
System.out.println("大家好");
count++;}
和while就是完全一样的了。因为迭代语句在循环体之后如果晕倒continue就会造成迭代语句得不到执行。
for 语句的初始化语句放在 for之前扩大初始化值得作用域。在循环里面只在循环中有效。for执行完了这些变量将不会再被访问。 还有就是额外定义一个变量来保存循环的值。不在循环体里定义在外面。(推荐)
循环变量选择时 i j k;
##嵌套循环
循环里嵌套一个循环 没有什么难的按照规矩一个一个的来解决。
内层循环当成外层循环的循环体。
##控制循环结构
没有goto 降低了灵活性。但是增加了可读性。java 提供了 continue break 来控制循环结构。 return可以结束整个方法。自然也可以结束循环。
###使用break 来结束循环。
某些时候需要在条件出现时强制终止循环而不是等false才终止循环。用break。跳出循环体。执行循环体后面的代码。
break 不仅终止本次循环还会终止外层循环。此时需要在break后面加一个标签。这个标签用于标识一个外部循环。
java中的标签用一个英文:的标识符。
public class BreakTest{
public static void main(String[] args){
outer:
for(int i=0;i<5;I++){
for(int j=0;j<3;j++){
if(j==1){
break outer;//跳出outer 所标识的循环
}
}
}
}
}
标识会终止标识所在的循环而不是break所在的循环。break后面的标签必须在break所在外层循环之前定义才有效。
##使用continue 忽略本次循环剩下的语句。
continue 中止本次循环剩下的语句。接着开始下一次循环。(不会出现在循环体的最后一行因为没有意义)。continue也可以后面接一个标签,用与直接跳过标识循环的档次循环剩下的语句。 必须是有标签。跳过去继续执行。
##return 结束用法。
return不是专门用来结束循环的。return是用来结束一个方法的。执行到return是方法就被结束了(return后面还可以接 变量 常量 表达式)
java中的循环大部分都在方法中。当执行到return时方法已经结束了,循环自然也就结束了。
return直接结束整个方法。无论在多少成循环中。
##数组类型
数组是编程一种常见的数据结构。 数组用于存储多个数据。每个数组元素存放一个数据。通常可以通过数组元素的索引来访问数组。 包括赋值和取值。
##数组也是一种类型
java要求数组要有相同的数据类型。在数组中数组元素的类型是唯一的。
java是一种面向对象语言。类与类之间存在可以支撑继承关系。这样可能产生一个数组中存放多种数据类型的假象。例如水果数组要求每个数组元素都是水果。苹果 香蕉 在数组里。都是特殊的水果。 子类是一种特殊化的父类。
一旦数组初始化完成数组所占的空间也将被固定下来。因此数组长度将不会改变。即使把某个元素清空。他所站的空间还会保留。依然是该数组数组长度不变。 java数组可以存储基本数据类型 和以用数据类型。只要数据元素有相同的类型即可。
值得是出的是数组本身也是一种数据类型。int基本类型int[]引用数据类型。
int[] 和别的一样的定义类型。引用类型 。可以创建对象。
###数组定义
type[] arryName;
type arrayName[]; (可读性差)(不推荐使用了)
两种语法格式推荐上面的一种。因为上面一个有更好的语义和可读性。 定义一个变量 ,变量名为 arrayName 变量类型是一个tpye[]数组。 前面已经指出type[]是一种新类型 与type不同。
数组是一个引用数据类型变量。定义式之定义了指针并没有指向内存。只有初始化数组才能使用。
定义数组时是不能指定数组长度的。
##数组初始化
java语言数组一定要被初始化才能使用,所谓的初始化就是给数组分配空间。
不能分配内存而不初始化,因为一旦为数组分配了内存,那内存空间储存的内容就是数组元素的值,即使内存储存空间是空的也是null值。不管以那种方式初始化数组只要数组分配了内存,数组就有了初始化值。
初始化的两种方法
1 静态初始化 程序员指定数组元素的每一个值,由系统决定数组长度
2动态初始化 初始化程序员只决定数组长度,由系统分配初始值。
静态初始化
格式
arryName= new type[]{element1,element2...}
数组中前面的type就是数组元素的类型。后面的元素必须和其类型一致。(可以是指定类型的子类)并使用花括号把所有的数组元素括起来。多个数组元素之间用,分开 定义初始化的花括号紧跟在[]之后。
Object是所有类的父类。
静态初始化简化的语法格式。
type[] arrayName = {element1,element2...}
只有在定义数组的同时进行初始化才能这样写。(实际开发中常用)
##动态初始化
动态初始化只指定数组长度。由系统为每个元素指定初始值。
arrayName = new type[length];
在上面语法中需要指定一个int类型的length参数。这个参数巨顶数组的长度,也就是数组元素的个数。注意type也和制定的相同。或者是其子类。
动态初始化程序员指定长度也就是所占的空间。系统将负责为其分配初始值。
基本类型中的整数 为o int long byte short
浮点数0.0 float double
字符 \u0000 char
布尔型 false
引用类型 null 类 接口 数组
不要同时静态动态初始化 不要再数组初始化时即指定长度 也分配每个元素的值。
使用数组 赋值 取值 获得数组长度
###使用数组
在数组后[]里面写上索引值。这样就可以访问数组元素了。
java语言的数组索引从0开始。月也就是说第一个是0 后面就是长度-1
如果访问数组元素的值小于0,或者大于等于数组长度,便宜不会有任何问题,但运行时会出现异常。 java.lang.ArrayIndexOutOfBoundsException:N(数组索引越界异常)
N就是索引值
说有的数组都有一个length属性,通过这个属性可以访问数组长度。获得数组长度就可以遍历数组的每一个元素。
##foreach循环 JDK1.5 以后有的
foreach循环用于便利数组和集合的每一个元素。 使用时不用获得数组和数组长度。无需根据索引访问数组元素和集合元素。
语法格式
foe(type variableName :arry|collection){
//variableName 自动迭代访问每一个元素
System.out.println( 元素);
}
与普通循环不同的是 不需要循环条件 不需要迭代语句这些部分都有系统来完成。自动得带数组每一个元素,迭代完成后自动结束。
不要对循环变量赋值没有意义 输出的是那个你定义的值
for(String book : books){
book = "jiangyi";
System.out,println(book);
}
都是jangyi 没别的对原数组没影响。
可以看出定义的变量只是一个临时变量数组会把元素依次赋值给这个临时变量,而这个零食变量并不是数组元素。他只保存数组元素。
foreach循环迭代数组元素时,并不能改变数组元素,因此不要对foreach的循环变量进行赋值。
###深入数组
数组只是一种引用数据类型。数组引用变量只是一种引用。数组元素和数组变量在内存中是分开存放的。
内存中的数组
数组引用变量只是一种引用,这个引用变量可以指向任何有效的内存。有效内存才有意义,
与引用变量相同的是,引用变量是访问真是对象的根本方式。也就是说访问数组对象本身只有通过他的引用来访问他。
数组对象存放在对内存中(heap)如果引用数组对象的变量是一个局部变量他就被储存在栈内存中。(stack)
如果要访问数组的摸一个元素,就要有数组[index]来访问。数组引用变量是访问堆内存中数组元素的根本方式。
方法运行时每个方法都会建立自己的内存栈,方法定义的变量将会逐个放入这块内存中。随着方法执行结束这个方法的栈内存自动销毁。方法中的变量是在占内存中,
程序创建一个对象时,对象被保存到运行时数据区中,以便反复利用。(对象创建成本通常较大)这个运行时数据区就是堆内存。对内存中的对象不会随方法的销毁而销毁。既方法结束后这个对象还可能被别的变量引用。方法传递参数时常见。这个对象依然不会被销毁。只有当一个对象没有任何引用变量引用他时,系统的垃圾回收器才会在适合的时候回收它。
为了让垃圾回收一个数组可以把数组变量赋值为null 也就切断了数组与实际数据之间的联系。数组也就成了垃圾。
是要数组类型兼容可以让一个数组的指针指向另一个类型的数组。
要看到程序的底层 看待一个数组时 一定要把数组看成两个部分,1 数组引用也就是代码定义的数组引用量。2实际对象 这部分在对内存里运行,通常无法直接访问他只有通过数组的引用变量来访问。
###基本类型数组的初始化
基本类型数组而言数组元素的值直接存储在对应的数组元素中。初始化时先为数组分配内存,然后将数组元素的值存入对应的数组中。
栈 堆 两个初始化直接在堆内存中放入基本值。
###引用类型数据的初始化
引用类型的数组的数组元素是引用。因此情况变得复杂,每个数组元素里存储的还是引用,他指向另一块内存。这块内存里储存了有效数据。
记住方法里的引用变量都是在栈内存中。指向堆内存。 及分给两个内存。
###没有多维数组
java语言里支持多维数组。但是没明确定义(底层运行机制上来看)。因为数组本省也是引用数据类型,所以只是数组里的元素也是数组,
typr[] arrayName 一维数组(典型的)
所以只是把type变成negtype[]
type[][] arrName;
java用上面的语言定义二维数组。(相当于初始化一个一维数组)
初始化
arrName = new type[length][]
初始化一个一维数组。数组长度length 同样因为这个一维数组元素是引用类型的所以数组为每一个初始化为null
当然元素也是数组,在运行时还要再次进行初始化。
java是强制类型语言。在定义数组是已经定义了其中的元素类型,所以只能按要求来。无限扩展的数组要把类型定义为Object才可以。
初始化二维数组 可以只制定左边维的大小 也可以同时指定两边维度的大小
int[][] b= new int[3][4];
还可以静态初始化二维数组,使用静态初始化二维数组是二维数组的每一个元素都是一维数组。
java 8 增强的工具类
java提供的
Arrays类里面包含一些static修饰的方法可以直接操作数组。static方法可以直接通过类名.调用
int binarySearch(type[]a,type key) 二分发查找key元素值在a数组中的索引。 a无key元素是返回负数。调用该方法时要确保数组元素按升序排列。
int binarySearch(tpye[]a,int fromIndex,int toIndex,type key)与前一个相似但是只是搜素从from 到 to之间的 得到索引
type[] copyOf(type[] original,int length) 复制数组 length 小于原数组长度就截取前面的 大于就后面自动初始化,
type[] copyOfRange(type[]a original,int from,int to)复制 只复制从from 到to 索引的值。
boolean equals(type[] a,type[] b)如果a b 两个数组长度一样 并且元素也一一相同,该方法返回true。
void fill(type[]a,type val) 放法把a所有元素赋值为val
void fill(type[]a,int fromIndex,int toIndex,type val)与前面的相同只是把 a 数组 从from到to填充
void sort(type[]a)对a数组进行排序
void sort(type[]a,int fromIndex,int toIndex)类似从from 到to排序。
String toString(type[]a) 该方法按顺序吧多个数组元素连缀在一起,多个数组元素有英文,和空格分开。
Array在java.utill包中,在程序中使用Arrays,要导包。import
除此之外在System类里也包含一个static void arraycopy(Object src,int srcPos,Object dest,intPos ,int length)可以把src数组的值赋值给dest中
增强了功能提供了CPU的性能
充分利用更好的硬件
void parallelPrefix(xxx[] array,XxxBinaryOperator op)
(binary)二进制的 op参数指定的计算结果作为新的元素。op半酣left right 两个形参。left代表数组前一个索引处的元素。right代表数组中当前索引的元素。带计算第一个时left默认为1
void parallelPrefix(xxx[] array, int fromIndex,int toIndex,XxxBinaryOperator op)一样就是计算from到to索引的元素。
void setAll(xxx[]array,IntToXxxFunction generator)指定的生成器为所有数组元素设置,该生成器控制数组元素的值的生成算法
void parallelSetAll(xxx[]array,IntToXxxFunction generator)和上面一样就是增加了并行能力。
void parallelSort(xxx[]a) 排序增加并行能力提高性能
void parallelSort(xxx[]a,int formIndex,int toIndex)一样就是有索引区间
Spliterator.OfXxx spliterator(xxx[]array) 该数组所有元素转化成对应的Spliterator对象
Spliterator.OfXxx spliterator(xxx[]array,int starInclusive,int endExclusive)一样就是有索引区间
XxxStream stream(xxx[] array)数组转化成Stream(流式编程API)
XxxStream stream(xxx[]array,int startInclusive,int endExclusive) 加上了索引区间
parallel开通的方法都表示,可以利用CPU并行能力来提高性能。
###数组中的应用举例
程序中多个类型相同的变量,有整体的逻辑结构,则他们可以定义成为一个数组
用来存放一类的数据值。有一定的顺序关系,可以更好的体现出来。
##面向对象
java提供了定义类,成员变量,方法等基本功能类可以认为是自定义的数据类型,可以使用类来定义变量。所以使用类定义的变量都是引用比那辆。他们将会引用到类的对象。 类是描述客观事物的某一类对象的共同特征,对象是类的实体。java中使用构造器来创建该类的对象。
封装 private default protected public
继承 entends(实现类复用的重要手段) 组合关系
多态 (子类传给父类的变量还能表现出子类的行为)
构造器用于对类实例进行初始化。支持重载。构造器包含相同的初始化代码,则就可以把这初始化代码放到普通初始化块里完成。初始化块总在构造器执行前调用。 java提供静态初始化块,静态初始化块用于初始化类,在类初始化阶段执行。 如果继承树某一类需要初始化,系统将会初始化该类的所有父类。
###类和对象
类 引用类型 自定义类型 引用变量 可以用于定义变量
###定义类
类class 对象 (Object 也叫instance(实例))
创建类定义语法
[修饰符]class类名{
零到多个构造器定义
零到多个成员变量
零到多个fangfa
}
修饰符 private final abstract 类名是一个合法的标识符。语法 实际
多个单词链接 每个单词首字母大写
类里的成员定义顺序没有影响,各个成员之间可以相互调用。但是需要指出的Static修饰的成员不能访问没有Static修饰的成员
成员变量,用于定义该类后实例对象的状态数据。方法则用于定义该类或该类实例的行为特征或是功能。构造器用于构造该类的实例。java语言通过new来构造返回对象的实例。
构造器是创建对象的根本途径,类没有构造器这个类无法创建实例。因此java提供了默认的构造器(只有当没有事才会提供,写了一个的话就不会在提供)
定义成元变量的语法
[修饰符] 类型 成员变量名[=默认值]
语法格式说明
修饰符 可以省略 也可以是 public protected private static final 其中public protected private 三个最多可以出想一个 可以与static final组合起来
类型 java允许的各种类型 基本类型 引用类型
成员变量 合法的标识符 通常 一个多个单词链接 第一个单词首字母小写其他的单词首字母大写单词单词之间不用任何分隔符,建议使用英文
默认值 成员变量可以指定一个可选的默认值
成员变量 是由field意译过来的 实际上java属性指的是set get方法。feild也有叫字段或是域的
定义方法的格式
[修饰符]方法返回值类型 方法名(形参列表){//一条或多条可执行语句组成的方法体}
说明
修饰符 可以省略 可以是 public protected private static final abstarct 其中public protect private 三个最多出现一个。 abstract 和final最多出现之一 他们可以与static联合使用
返回值类型 可以使java允许的任何数据类型,包括基本类型和引用类型。如果声明返回值类型,则方法必须有一个有效的return语句。该语句返回一个变量或表达式。要与声明的类型一致。 如果没有返回值要用void来表述
方法名 方法名的命名规则和成员变量相同。但是方法一般表明这个类或是实例化对象的行为和特征建议动词英文开头
形参列表 用于定义方法可以接受的参数。形参列表由一组或是多组 “参数类型 参数名”组合而成 多组参数由疑问,分隔开来 形参类型和形参名一定要有英文空格分隔 定义了形参调用的时候就要传入 谁调用谁来给形参赋值。
方法体里的语句块有有严格的先后执行顺序。前面的语句永远在后面的语句之前执行。
static一个特殊的关键字 用来修饰方法和成员变量 表示这些方法或是成员变量属于这个类本身。而不属于这个类的单例实例(静态变量静态方法)。 通常叫做类方法或是类变量。不是累的就是属于单例的 不修饰叫做实例变量或是实例方法(非静态方法 非静态 变量 )。
静态成员不能访问非静态成员。
static 就是区分 成员变量 方法 内部类 初始代码块4种成员到底是类本身的还是属于实例的
构造器就是特殊的方法
[修饰符]构造器{参数列表}{//零条到多条可执行语句组成的可执行构造体}
说明
修饰符 可以省略 private public protected
构造器 构造器的名称一定要和类名相同
形参列表和定义方法定义形参列表相同
值得指出构造器不能定义返回值。也不能使用void盛名构造器没有返回值。编译不会出错,但是会把他当作方法来处理而不是构造器
java与法规定构造器无返回值,new 构造器 返回的是该类的实例 返回的总是当前的实例 不能用return返回当前对象 因为构造器的返回值是隐式的
系统在创建类发现程序员没有写构造器就会自动添加一个默认构造器 (无参构造)
java类大致有如下作用
定义变量
创建对象
调用类的方法或访问类的变量
##对象的产生和使用
构建对象的根本途径是构造器、用new关键字第哦啊用某个类的构造器即可创建这个类的实例。
type p =new type();
java对象的作用
访问对象的实例
调用对象的方法
访问条件允许 类里定义的任何方法和成员变量都可以通过类或实例调用。语法是 类.类变量|方法 实例.实例变量或是方法 类或实例是主调者。用于访问该类或是给实例的成员变量和方法
static 可以通过类来调用 也可以通过实例来调用(不推荐 改变整个类的属性) 没有的只能通过实例来调用
类不是一种具体的存在 对象才是 类就是些的综合 static修饰的就是共性 没有的就是实例对象不同的内容,当时会有
###对象和指针
先是有这个实例化(创建对象) 然后是把引用传给变量(指针(java中没有指针概念只是把指针封装起来有java语言本身底层控制))
类也是引用数据类型 变量在栈里 指向堆内存中的一块内存。(heap)
栈里的引用变量没有成员变量 成员变量适合对象一起储存在heap内存中的
java不允许直接访问堆内存中的对象 只能通过引用来访问
无论数组还是对象,程序员访问引用变量的成员方法时。实际上是访问该引变量所引用的数组、对象的成员变量或方法。
堆内存中的对象可以有多个引用。就是说可以有多个变量指向一个对象。
对内存中的对象没有任何引用,没有方法访问他就成了垃圾 垃圾回收。希望提醒垃圾回收机制回收某个变量就只用把他的引用变量设置为null
##this 的用法
总是只想调用该方法的对象
用法
构造器中指向该构造器正在初始化的对象
在方法中引用调用该方法的对象
this最大的作用让类中的一个方法,访问该类中的另一个方法或实例变量。
this调用的是本身,不会产生新的对象,不会占内存。 this可以代表任何对象,方法中this代表的对象是不确定的但是类型是确定(类型只能是当前类 谁调用this this就代表谁)
对象方法中还用在创建一个对象调用其中的方法 依赖关系
大部分 一个方法访问该类定义中的其他方法,成员变量时加不加this前缀效果一样 (不推荐){假象只是省略了this 常常把调用成员变量、方法的对象称为主调 对java 调用成员变量 方法时 主调必不可少 即使代码中省略主调但是实际中还是存在的 一般来说 调用atatic修饰的成员省略主调默认该类做为主调 没有static修饰的成员省略了主调 this 默认为主调}
static 修饰的直接可以用类来调用。这是后里面如果有this指的是对象。但是对象还没有建立。没法指向。因为没有this所以静态方法不能访问不使用同类中的静态成员 及 静态成员不能直接访问非静态成员。
java允许实例对象调用类方法,这并不是好的容易混淆 所以一定要注意。自己写的时候不要这样弄
确实要在静态方法中访问一个普通方法 就一定要创建一个对象。
大部分情况下普通方法访问其他方法成员变量时无需使用this 当时方法有局部变量和成员变量同名。当程序又需要在该方法里访问这个被覆盖的成员变量必须加this (不在一块内存上 随便赋值 一块内存上能出现相同的情况)。
构造器中代表初始化对象 构造器 new调用 不是使用对象调用
访问普通变量一样访问this 并且 this可以作为返回值
this代码简单但是可能就会意义模糊
##方法详解
java 方法不独立存在 逻辑上 方法要不属于类 要不属于对象
方法的所有属性
结构话编程语言 方法是公民做成程序
面向对象中 类是一个公民 方法属于类或对象
java语言是静态的,一个类定义完了以后只要不重新编译 该类和该类的对象拥有的方法是固定的 永不变
执行方法必须有调用这, 类.方法 对象.方法
java 语言中方法
方法不能独立定义 只能定义在类里
逻辑上讲方法要么属于该类本省 要么属于该类的对象
永远不能独立执行方法,执行方法必须使用类或对象作为调用者
###方法参数的传递机制
如果方法中包含形参声明 主调者调用这些方法时必须给定这些形参的实际参数。
java的实参是值传递 值传递就是把实际参数的副本传入方法内,而参数本身不会受到影响。(无论怎么处理这个参数原值不会受到影响)(方法体里的变量相当于局部变量不影响外面的 )
一个方法一个栈 ,一个栈一块内存。
java对于引用类型的传递也是值传递,传递的是指针 指向的是同一个对象。也就造成了值的变化。
(创建对象 传递至 有内存)
##形参个数可变的方法 (JDK 1.5)
允许定义形参个数可变的的参数,从而允许为方法指定数量不确定的参数。在定义方法时,最后一个形参后面加3点(...)表示可以接受多个参数。多个参数被当成数组传入
(形参个数可变的参数本质就是一个数组)
public static void test(int a,String ... books)
public static void test(int a,String[] books)
两种定义方法完全一样。 就是调用时可变形参的方法跟家简洁。指出数组形式的形参可以在定义的各个位置,但是可变形参只能在最后的位置)
长度可变的形参只能在最后,一个方法中只能包含一个长度可变的形参。调用的时候可以传入一个 也可以传入一组参数。
###递归方法
一个方法体内调用它自身 成为方法递归。(隐士循环一定要注意循环条件的把控)
无穷递归 死循环 定义递归方法时重要规则 递归一定要想已知方向递归(有头)
递归 访问路径下的文件。
##方法重载
java允许一个类里面定义多个同名的方法,只要形参列表不同就行。 雷利包换两个或两个以上的方法名相同,但参数形式不同 则成为方法重载
确定一个方法
调用者 方法所属者 既可以是类也可以是对象
方法名 方法标识
形参列表 调用方法时系统会根据传入的实参匹配
重载要求两同一不同/同类 同方法名 不同参数
(返回值 修饰符与重在无关)
调用方法的时候很多情况下是忽略返回值类型的。所以不能用返回值确定
在编程中能让系统糊涂 必须要确保每一个的准确可识别
重载方法里定义了长度可变的参数
系统会从小范围的开始 再到大范围的 如果想调用的是确定的可变参数方法。可以传入同样类型的数组来处理。(不推荐用可变长度的方法)
###成员变量和局部变量
所有变量 成员变量{(实例变量 不用static修饰) 类变量 (用static修饰的)} 局部变量(方法里定义的){形参 (方法中值传递过来的) 方法局部变量 (在方法内定义的) 代码局部变量 (在代码块中定义的)}
类变量在类准备阶段就开始存在,知道系统销毁这个类。类变量的作用与是类的生存相同范围 ,实例变量就是要在实例对象的时候才开始创建。知道系统销毁这个实例。 作用域对应的是实例的存在范围
一个类在使用之前要经过 类加载 类验证 类准备 类解析 类初始化等几个阶段,
一个实例修改了类变量,就会造成其他实例来取值时拿的是修改过的类变量
成员变量不用显示初始化,系统会在类的准备阶段,或是类的实例阶段进行默认的初始化。默认初始化和数组初始化相同。
成员变量除了形参意外都要显示的初始化。就是说必须给局部变量或是代码块局部变量指定初始化值,否则不可以访问他们。
栈内存中不用的机会销毁
形参 作用于在整个方法体内有效 并且无需显示的初始化,形参的初始话,在调用方法时由系统完成。形参的制定有调由者完成。 栈内存创建对象 值传递给值。
内存在一块的不能出现重名现象 成员变量名不同 方法局部变量也不能同名
成员变量与方法局部变量可以重名,只不过在调用的时候,要用this.成员变量名 或是类名. 成员变量名 不能直接用变量名。(自己写的时候不要出现这种情况)
##成员变量的初始化和形同内存中的运行机制
在系统加载类 或是穿件该类的时候会自动为其分配空间。并在分配内存后在动为成员变量指定初始值。
初次使用一个类 首先会加载这个类和其父类 并初始化该类,在类的准备阶段分配空间。设置默认初始值。
创建对象的时候 栈内存创建的变量指向 堆内存中创建的对象。
###局部变量的初始化和内存中的运行机制
局部变量要显示的初始化,就是说局部变量定义的时候没有分配空间。直到赋值时。才会为局部变量分陪内存。
成员变量不属于任何类或是实例。总是在方法的栈内存上。如果是基本类型变量据储存在上面 如果是引用数据类型就存放的就是地址。站内存的变量无需系统回收,随着方法或是代码块的结束而结束。局部变量的内存站的小
###变量的使用规则
都用成员变量的害处
扩大了变量的生存空间,到这内存开销
扩大了变量的作用域,不利于提高升序的内聚性,
软件开发规范就是搞内聚 低耦合
成员变量
描述某个类或是实例对象的固有信息。
用来保存该类或实例运行时的状态情况
信息要在某个类的多个方法之间共享。信息用成员变量来保存。
使用成员变量也要尽可能的缩小变量的作用范围。能用代码块局部变量的就一定不要用方法局部变量
###封装和隐藏
封装 对象信息隐藏在对象内部。不允许外部程序直接访问对象内部的信息。而是通过该类提供的方法来实现对内部信息的操作和访问。
良好的封装 目的
隐藏该类的实现细节
让使用者通过预先设计的方法来访问数据。从而可以加入控制逻辑,限制队成员变量的不合理访问。
进行数据检查是有利于保证对象的完整性
便于修改,提高代码的可维护性
实现封装要考虑
将对象的成员变量和实现细节隐藏起来不允许外部直接访问
把方法暴露出来,让方法来控制这些成员变量进行安全的访问和操作。
通过java访问控制符实现
###使用访问控制符
private default(包访问) protected public
从小到大
private (当前类访问)常用修饰成员变量,隐藏起来制定方法暴露出去
default(包访问权限) 没有修饰符的 可以被本类和同一个包中的其他类访问
protected (子类访问权限) 可以本类 一个包中的其他类 其子类访问(通常protected来修饰一个方法,其子类来重写这个方法。)
希望其子类来重写这个访问权限
public(公公访问权限) 最宽松的访问权限 任何的类都可以访问
局部变量 作用域就是他所在的方法。不可能被其他的类访问。不用使用访问修饰符来修饰
对于外部类来说,只能有两种修饰 public 或是默认的 。private 和protected没与意义
(对普通类(没有内部类的类)来说,内部类和外部类都与他无关;对有内部类的类来说,它们就是其内部类的外部类,外部类是个相对的说法,其实就是有内部类的类。
所以,要回答这个问题,只需要讲解内部类是什么:
Java中的内部类共分为四种:
静态内部类static inner class (also called nested class)
成员内部类member inner class
局部内部类local inner class
匿名内部类anonymous inner class)
源文件名要和内部有public修饰的类同名
setter getter方法 指的就是私有的成员变量修改和调用的方法(提供的外部访问接口) setAge() getAge() 两个的成员方法。注意变量名大写两个的单词。
如果一个java类的每个实例都被private修饰的,并且都提供了setter getter方法,那么这个类就是一个符合JavaBean规范的类。因此JavaBean总是一个封装良好的类。
一个类就是一个小模块,应该只公开必须让外界知道的内容,而隐藏其他一切内容。 进行程序设计师应该尽量避免一个模块直接操作和访问令一模块的数据。模块设计追求高内聚(尽可能把模块内部数据,功能实现细节隐藏在模块内部独立完成,不允许外部直接干预。)低耦合(仅暴露少量的方法给外部使用)
关于访问控制符的使用
类里绝大部分变量都应该使用private修饰,只有一些static修饰的类似全局变量或成员变量,才能使用public修饰。 有些方法只用于辅助实现该类的其他方法,这些方法被称为工具方法,工具方法也应该使用private修饰
如果某个类主要用作其他类的父类。该类的大布分方法可能仅希望被其子类重写,而不像被外部调用应该用protected修饰
希望其他类自由调用的方法应该是用public修饰
类的构造器通过使用public修饰,从而允许在其他地方创建该类的实例。
外部类通常希望被其他类使用,所以外部类都是用public修饰
###package import inport static
java 引入包(package)机制,提供了类的多层命名空间,用于解决类的命名冲突,类文件管理的问题。
java允许把一组功能相关的类放到同一个package下。从而组成逻辑上的类库单元。
java源文件中使用了package语句。源文件定义的所有类都属于这个包。位于包中每个类的完整类名都应该是包名和类名的组合。其他人需要使用该包下的类。也应该是用包名加类名组合。
javac -d . Hello.java
-d用来设置生成编译生成的class文件保存的位置。.指的是当前路径。
java规定 位于包中的类,在文件系统中也必须有与包名层次相同的目录结构。 用有-d的javac会自动生成包结构对应的文件夹。只用javac就不会生成相应的包结构
包结构也是用.该连接的类名。
虚拟机要装在一个类是 去找classpath中的各个目录。找到对应的包然后就是对应的文件结构下的类。
同一个包中的类可以不放在同一个目录下。写了就行虚拟机回去找并放入同一个包中。同理java原文件也应该放到同样结构的包文件结构中 防止出粗冲突。
不是有了目录结构就有了包名,而是要在原文件中声明package单靠目录是没有办发确定的。java包机制需要 1 源文件中使用package制定包名 class文件必须放在对应的路径下。
java语法规定包名只要是有效的就可以,但是从可读性的角度来说,包名就应该全部是小写字母。而且应该由一个或是多个有意的单词连缀而成。
建议 使用公司的Internet域名到写来作包名。 还可能会有模块名
package语句必须作为源文件第一条非注释性语句。一个源文件只能定义一个包 ,可以定义多个类。类全在包下
没有package就是默认包下。(注意请示做都会有包)
子包并不属父包中的类的类宅又是也要是有全类名或是导包。
父包和子包确实表示了某种内在的逻辑关系。子包是父包的一个模块,但是父包和子包在用法上则不存在任何逻辑关系,如果父包的类需要使用子包中的类必须使用全类名
创建其他包下的类的实力,则调用构造器时也需要使用该类的全名。
为了简化编程java提出了import关键字 import关键字可以导入指定包层次下某个类或全部类(使用*通配符)但是不能导入子包下的类。
全部的要用...*才行
一个java源文件只能有一个package 可以有多个import 导入import必须在package包下面。
import 但如后就可以不用使用全类名,省略包前缀。但是当导入的包中有同名的情况就要注意了。还是要使用全类名来区分开。
java默认导入java.lang包下的所有类,所以使用String System不用导包。
import 可以导入包下的某个类也可以导入包下的全部类。
import static 静态导入 分别指的是导入制定类单个静态成员变量、方法和全部成员变量、方法。确定到单个的成员比那辆和方法。import 和import static一样没有区别(可以省略类名)。
import关键就是为了简化代码提出来的。
###java的常用包。
java核心类在java包下,java拓展类在javax包下。这些使用类也就是前面说的API
java.lang String Math System Thread
java.util Arrays List Set
java.net java网络编程的类/接口
java.io java输入输出编程的就扣
java.text java格式化相关的
java.sql java进行JDBC数据库编程相关的类/和接口
java.awt 抽象窗口工具集
java.swing Swing图形用户编程相关的类/接口
##深入构造器
java类必须有一个或一个以上的构造器 构造器是创建对象的重要途径(工厂模式 反射 创建对象的时候 依然依赖于构造器)
###构造器的初始化
构造器的最重要用途就是构造对象时候进行初始化。
java程序员没有为java类提供任何一个构造器系统会提供,如果提供了系统就不会提供,
想改变构造器进行的默认初始化可以显示的对其进行赋值。
public 类名(形参(显示初始化的值)){}
构造器是创建java对象的重要途径,通过new关键字创建对象的时候。实际上当系统调用构造器时 系统会自动为该对象执行默认初始化,这个对象已经产生了这些操作构造器执行之前就完成了。也就是说在执行构造器之前就已经创建了一个对象。只是这个对象是外部无法访问的。只能在构造器中通过this来引用。构造器执行体执行结束后,这个对象作为构造器的返回值被返回,通常还会复制给一个引用类型变量,从而外部程序可以访问该对象。
可以构造器重载提供多个构造器。
构造器主要用于被其他类调用。public居多 ,特殊请款gprotected
###构造器重载
一个类中多个构造器,形参列表不同构成构造器重载。造成多个初始逻辑。从而构造不同的初始java对象
系统中一个构造器的执行体包含了另一个构造器的执行体 用this来做。
this(); 构造器参数看情况 this代表的就是对象就是类名。
使用this调用另一个重载构造器只能在构造器中使用。而且必须是构造器执行体第一条语句。this调用重载构造器时,系统会根据this后括号里的实参来调用形参列表与之对应的构造器。
用this代替代码重复的好处
软件开发规则 不要把相同的代码书写两次以上 因为软件是一个不断更新的产品。 可以更好的更改 避免代码重复出现充分服用每一段代码。让代码简洁,降低维护成本
###类的继承
java里每一个类都只有一个直接父类。间接父类就多了
####继承的特点
继承用extends来实现。实现继承的类被称为子类。被继承的类是父类(超类 基类)(extends扩展的意思) 子类是一种特殊的父类 父类代表的方位要比子类大。
语法格式
修饰符 class SubClass extends SuperClass{
//类定义部分
}
java单继承 只有一个直接父类 无限个间接父类 集成的子类有父类的所有属性方法构造
没有写默认集成Object 所有类的父类 直接 简介父类
从子类角度讲 子类拓展父类,但从父类角度讲 父类派生 derive 处了父类 扩展和派生是同一个动作 只是角度不同。
##重写父类的方法
子类总是衣服类为基础,额外的加新的成员变量和方法,但是有一种情况例外,子类需要重写父类的方法。((Override) 也被称为方法覆盖。
###方法重写遵循“两同两小一大” 同方法名 同参数列表 子类返回值类型 和抛出的异常相同或是更小。一大访问权限要比父类的大或相等。
指出覆盖方法和被覆盖方法要是一样的 要么是类方法 要么是实例方法不能一个是类方法一个事实例方法。(编译出错)
覆盖以后子类的对象不能调用父类被覆盖的方法。倒是子类方法中可以调用。使用关键字super(被覆盖的是实例方法)或是父类名.(被覆盖的方法)。父类的private修饰的方法对子类是隐藏的。子类无法访问也就无法重写。 如果子类中定义了一个与父类private相同的方法。 不是重写,而是一个新的方法。
方法重载 Overload 同一个类多个同名
方法重写 Override 发生在子类和父类之中
子类中可能发生重载,和继承下来的父类的方法发生的也是在一个类里面的。
##super 限定
在子类中调用被覆盖的父类的实例方法使用super来调用。(静态的还是用类名.调用)
public void callOverridedMethod(){
//在子类中通过super 显示调用的父类方法实例
super.fly()
}
super 关键字又来调用他从父类继承来的实例变量或是方法。
this 和super一样不能调用static修饰的方法或是变量。
代码调用的时候都是找最近的。
子类中与父类同名的变量或是方法会隐藏父类中的内容。就会不能调用父类的方法。用super关键字解决
这种情况
实际上在创建时会为子类创建两块内存区域。一个储存自己定义的 一个储存父类定义的。 super指定去找父类的。
如果子类里面没有包含和父类同名的成员变量,那么在子类的实例方法中访问该成员变量时,无需显示的使用super或父类名作为调用者,如果访问名为a的变量调用。但没有显示的指定调用者。系统的查找顺序是
1 查找该方法中含有名为a的变量
2查找当前类中包含名为a的变量
3查找直接父类为a的变量 一次向上查找。知道Object类查不到就编译错误
类变量被覆盖,在子类方法中通过父类名作为调用者来访问被覆盖的变量。
当创建子类对象时。系统不仅会为该类中定义的实例变量分配内存,也会为他从父类继承得到的分配内存。(父类 直接父类 简介父类)
变量子类中定义了和父类同名的时候会隐藏父类的变量 ,不是覆盖。因此系统创建子类对象时,依然会为父类定义的。被隐藏的变量分配内存空间。
子类方法中访问父类中定义的,被隐藏的实例变量,或为在子类方法中调用父类中定义的、被覆盖的方法都可以通过super作为限定来调用这些实例变量和实例方法。
实例变量不会覆盖只会隐藏。 (分配地址的时候会有他的内存)。
转载于:https://www.cnblogs.com/liu123456789/p/6262409.html