高级语言运行机制 ........................................................................................................................... 2
java 编译路径 .................................................................................................................................. 2
java垃圾回收机制(GarbageCollection ) ................................................................................... 2
结构化开发、面向对象 、 基于对象(javascript).................................................................... 3
生成API文档 ................................................................................................................................... 3
参数........................................................................................................................................... 4
运算符....................................................................................................................................... 5
JAVA关键字 ...................................................................................................................................... 6
流程控制........................................................................................................................................... 6
数组 .................................................................................................................................................. 8
面向对象上....................................................................................................................................... 9
成员变量 ................................................................................................................................. 10
局部变量 ................................................................................................................................. 11
变量的使用规则 ..................................................................................................................... 11
封装......................................................................................................................................... 11
继承......................................................................................................................................... 12
组合......................................................................................................................................... 13
初始化块 ................................................................................................................................. 13
面向对象下..................................................................................................................................... 13
加强封装类(wrapper class ) ............................................................................................. 13
处理对象 ......................................................................................................................... 15
补充 ................................................................................................................................. 22
高级语言运行机制
1. 高级语言运行机制可分为编译型和解释型;
编译型语言是指用专门的编译器对专门的操作系统进行一次性的“翻译”为机器码,编译生成的可执行文件可以脱离开发环境在专门的平台上运行。运行效率高。但是移植到其他平台需要进重新编译或者修改所以移植性比较差,比如C/C++;
解释型语言是指用专门的解释器对源程序进行逐行翻译成特定的机器码并立即执行。因为每次执行都需要解释解所以释型语言效率较低。但是移植性较好,如Ruby。
而java是一种先编译后解释的语言;java源代码由编译器进行编译,生成字节码文件(*.class),生成的字节码是不可执行文件并且与平台无关直接面向JVM,经过JVM的解释后生成可执行文件。不同平台的JVM是不同的但是对生成的字节码文件有同样的接口,所以在保证效率的情况下又有很好的移植性。
2 JVM标准:指令集 寄存器 类文件的格式 垃圾回收堆 栈 存储区 java 编译路径
1. javac -d . helloworld.java (“-d”代表字节码存储路径 ,“.”是当前路径 也可是本地磁盘上的其他有效路径)
2. 临时指定JRE搜索Java类的路径可使用 “-classpath”:java -classpath dir1;dir2;..........;dirN. WIN 分隔符为“;” linux 平台上以":" 分隔 。
如果要指定的路径和当前路径都有效则为:java -classpath %classpath% ;.; dir1;dir2... 。 1.5版本的JDK可以不配置classpath路径
java垃圾回收机制(GarbageCollection )
1. GC不但可以回收不在被引用的对象还可以清除内存中的记录碎片,将所占用的对内存从对象中间的空闲内存移到堆的一端。
2. 分配出去的内存得不到收回,就会引起系统运行速度下降,甚至瘫痪。这种现象叫做内存泄漏,内存不够用。
3. 可以用System.gc()和finalize()来建议虚拟机进行垃圾回收。
4. 在程序编写时,对于不在引用的对象不要引用。如果引用的话则对象不能被GC及时回收,从而导致内存越来越少,GC试用频率会越来越高,导致系统性能下降! 结构化开发、面向对象 、 基于对象(javascript)
1. 结构化,从上到下逐渐细华。
2. java是一种先编译,后解释型语言。
生成API文档
1. javadoc常用选项 :
javadoc -help 查看命令选项;
-d
-windowtitle
-doctitle
-header
格式 javadoc+选项+原文件包 例如:javadoc -d 路径 -windowtitle 设置文档标题 *Test.java
Java 中的参数和类型
参数
1. Java整数常量会默认为int。赋值为byte或者short则默认为所赋值类型,但不会默认为Long ,错误如:long a=999999999999999999. 可写为long a=9999999999999999L.
注意:Java整数常量默认为int,故一个二进制整数常量默认为32位,第32位为符号位,如果在常量后面加L则第64位为符号位。
2. 源码——反码——补码 反码(符号位不变其他取反)
3. 位运算不会改变原操作数,只会生成新的数。
4. 新增以0b/0B开头的二进制数据如 :int a = OB1011011。
5. 字符型常量可以可以采用十六进制编码方式来表示, char类型值当然也可以当做十六进制来处理,表数范围0~65535就是说无负数。如果将int赋给char则会把该数值当成char对待。
6. 精确表示浮点数用BigDecimal类。543e2既54300为浮点类型!浮点类型默认为double,543f为float。
7. 所有的正无穷都相等,所有的负无穷都相等,NAN与任何数都不想等,包括NAN自身。
8. 只有浮点数(0.0除外)除以0才能得到无穷大,因为JAVA语言会自动把整数0转换成浮点数0.0。
9. “true”“false”不可以转化为布尔值 布尔值可以转化为字符串类型。
boolean b = true ;
String s = b+"a";
System.out.print(s);
输出结果 :truea
10. java 自动转换 byte 2位 int 4 位 long 8位 float 4位 “long->float?”
11. 任何基本类型的值与字符串运算都会转化为字符串。
int a=7,b=5;
String Str = "hello"; System.out.println("a+b+hello"); System.out.println(a+b+"hello"); System.out.println("hello"+a+b);
类型的自动提升: char a = 'a'; int b = 5; System.out.println(a); System.out.println(b+a); System.out.println(“hello”+a+b); System.out.println(a+b+”hello”);
12. math.random() 生成[0.0,1.0]双精度浮点型随机数。
13. 强制类型转换问题: 1. 内存溢出问题 2. Character/char int/Integer 3.字符串转换为基本类型parseXxx(String str)
14. 字符串直接量: 当程序第一次使用字符串直接量的时候JAVA会使用常量池来缓存该字符串,如果后面的部分需要使用的时候则程序直接调用常量池中的字符串。
常量池:指的是在编译阶段就被确定的.class文件所包含的类,接口,方法中的常量等数据,包括字符串常量。
String a = "hel"+"lo";
String b = "hello";
String c = "hello";
System.out.println(a==b);
System.out.println(a.equals(b));
System.out.println(b==c);
System.out.println(b.equals(c));
运算符
1. 位运算符: &,|,^,~ 按位与, 按位或,按位异或,按位非
左移运算符 :<< 左移指定位,右边0填充
右移运算符 :>> 和 >>>
>> : 右移指定位,左边符号位填充。
>>> : 右移指定位,左边0填充。
注意: 移位运算符只适合 byt,short,int,char,long等整形数据进行运算;对低于int类型的要先转换成int类型再进行移位运算;若移位数大于32则先求余后移位;long同理;移位运算不会改变原来的数,而是产生新的数;只要不发生有效位数字的丢失就相当于对数据乘以(左移)/除以(右移)2的位数次方。(总结:任意正数byte,short类都可进行左移)
2. 拓展运算符。如:+=,^=,<<=,>>>=。拓展运算符不但有更好的性能还可以提高程序的健壮性。
如: byte a = 5;//栈中没有byte,short,char,类型运算时会自动扩展为int型。 a = a + 5;
3. 错误,因为5默认为int类型,运算后等号左边为int型,而右边为byte型! byte b = 5; b+=5; 虚拟机中会自动强制转换,相当于,b = (byte)(b+5) 比较运算符:
”==” 若比较的是数值类型,则只要数值相同就返回true。如:5.0=5, ’a’=97;如果是引用类型则必须引用相同的类的实例才可以比较,只有引用的是同一个变量才能返回true,如果两个引用类之间没有父子继承关系则他们的变量也不能用”==”比较。
如:Connection conn1 = new Connection ();
Connection conn2 = new Connection ();
Connection conn3 = conn2;
System.out.println(conn1=conn2);
返回 false System.out.println(conn3=conn2);
返回 true
基本类型变量不能和引用类型用”==”比较!boonlean类型的变量不能和其他任意类型比较。”!=”同上。
4. 逻辑运算符:短路与或,非短路与或(|,&) , 异或:^(当两个运算符相同的时候返回true,反之返回false)
5.
6. 唯一的三目运算符:expression?true-statement:false-statement;
JAVA关键字
1. assert enmu instanceof(检测左边对象是不是右边对象的实例)
transient volatile
2. literal: true false null
3. 保留字: goto const native strictfp
流程控制
1. if …else语句试用原则:先处理包含范围更小的情况。
如 : package com.jh.test;
public class test_03 {
public static void main(String[] args) { } int age = 45; if (age > 20) { System.out.println("青年人"); } else if (age > 40) { System.out.println("中年人"); } else if (age > 60) { } System.out.println("老年人");
}
错误,只要是20岁以上全是青年人。
package com.jh.test;
public class test_01 {
} public static void main(String arg[]){ } int age = 45; if(age>60){ } else if(age>40){ } else if(age>20){ } System.out.println("青年人"); System.out.println("中年人"); System.out.println("老年人");
不能忽略else中隐含条件是对前面的条件取反,为了避免计算if和else中的集合问题,可以先处理if中条件范围较小的,如上所述。
2. switch…case语句: switch后的控制语句的类型只能是byte,short,char,int四个整数,枚举类型和java.lang.String类型(java7);switch 语句一旦遇到case中相等的值就会开始执行之后的代码块,直到遇到break!
3. do while , while,if.
4. break : 跳出本层循环,与“:”连用可以结束外层循环。
Continue :跳出本次循环(不执行本次循环中continue后的语句),继续进行下次循环。Continue也可与”:”标签连用,结束外部循环。
return : 直接结束整个方法。
数组
1. 数组一旦初始化长度就会被固定,因此数组的长度不可变,即使被清空数据后数组空间依然被保留。(数组即是一种数字类型也是一种引用类型)。
2. 数组元素动态初始化时由系统默认初始值:若类型为 整数型(byte,short,int,long)则初始值为0;若类型为 浮点值(float,double)则初始值为0.0;若类型为char则初始值为“\u0000”; 若类型为boolean类型则初始值为false;若数组元素为引用类型则初始值为null;
注意:数组定义时不能指定长度,不能在初始化的时候即给定长度也给定初始值。
3. 数组索引越界异常:java.lang.ArrayIndexOutOfBoundException:N
4. foreach循环可以更加简洁的便利数组和集合的每个元素。格式for ( type variableName : array | collection ){/自动迭代访问每一个元素。
如: public static void main(String arg[]){
String[] books = {"java编程思想","java疯狂讲义","think of java"};
} 输出结果:java编程思想 java疯狂讲义 think of java for(String book : books){ } System.out.println(book);
在循环语句中的变量为临时变量,所以对临时变量赋值不能改变原数的值,所以如果要对数组中的参数进行修改就不能使用foreach。
5. 数组变量的引用和数组实际的对象:数组对象存储在堆内存中,引用数组的变量被存储在栈中;每个法都会建立自己的内存栈,并把方法里定义的变量逐个放入,方法调用结束后销毁。程序中创建的对象都存储在堆内存(运行时数据区)中以便反复使用并且不会随着方法调用的结束而销毁。
数组引用的变化不会改变原数组的长度和数值,如:
int [] a = {2,3,4} int [] b = new int [4] ;
System.out.println(“赋值前是”+b.length);
b=a ;
System.out.println(“赋值后是”+b.length);
输出结果: 赋值前是3
复制后是4
虽然输出的数据发生了改变,但是堆中对象数组 a 和对象数组b的长度没有发生改变!只是栈中变量a,b的引用发生了改变,原来栈中变量b的引用指向堆中的对象数组b,赋值后栈中变量b的引用指向堆中的a!
6. 基本数组类型初始化:
int [] intArr ; 指定数组名,但没有分配内存空间(空引用),所以不能指定长度。 IntArr =new int [5] ; 通过new为数组分配内存,有了内存空间后便可以指定长度, for(int i = 0 ; i < intArr.length ; i++ ){
intArr = i+5; 指定长度后数组元素为系统默认值(int类型为0),通过操作基本类型数组的变量来对数组赋值。
7. 引用类型数组的初始化:
引用数组类型里的元素存储的还是元素还是引用元素。
8. 二维数组(一维数组的引用)
9. 操作数组的工具类 :
在Arrays类中的static方法,可以直接操作数组。
type[] copyOf( type[] original , int newlength) :复制远数组,如果原数组过大,截取newlength位,反之系统默认值补位。
type[] copyOfRange( type[] original , int from , int to ) : 从from位复制到to位,其他同上。boolean equals( type[] a, type[] b) : 如果数组a,b长度相同元素一一对应相同则返回true。 void fill( type[] a,type val ) :把数组所有元素都赋值为val。
void fill(type[] a ,int fromIndex , int toIndex ,type val): 同上,你懂得。
String toString(type[] a ) : 将多个数组元素转换为字符串,多个元素用“,”和空格隔开。
void sort( type[] a) : 对a元素进行排序。
void sort(type[] a ,int fromIndex,int toIndex): 同上。
面向对象上
1. 常见类包含三种成员(方法,构造器,Field)。
2. 构造器是一个类创建对象的根本途径,如果类没有构造器,那么程序自动添加一个默认的构造器。构造器支持重载。
3. 初始化块总是在构造器之前被调用,静态初始化块在类被初始化时被调用。如果继承树里某个类要被初始化,系统会初始化他的所有父类。
4. Static修饰的方法属于该类的,所以使用该类的任何对象调用这个方法时得到的结果是一样的,因为实际上还是使用这些实例所属的类作为调用者。
5. java里没有引用传递,全部是值传递,要么复制参数值进行传递,要么复制地址(引用变量)进行传递。
6. 形参个数可变的传递。传参时相当于把参数当成一个数组,但是无需是数组的格式。区别:数组形式的参数可以出现在形参列表的任意位置,但是个数可变的形参只能位于参数列表的末尾并且只能有一个长度可变的形参列表。
7. 递归: 只要有一个方法的方法体的实现中再次调用了方法本身,就是递归方法,递归一定要向已知的方向递归。
应用:用递归的方法去遍历某一目路径下的所有文件。
8. 重载:
同一个类中,方法名相同参数列表不同。 与修饰符,返回类型,等没有任何关系。 方法的返回值不能区分重载的方法:因为java调用方法时可以忽略方法返回值 ,如调用f()。
成员变量
1. 成员变量指的是在类里面定义的变量,既field;成员变量分为实例变量(非静态)和类field(静态)。类field生命周期从类准备阶段开始直到类被销毁。实例field从该类的实例被创建开始到系统回收。(类在使用之前要经过类加载,类验证,类准备,类解析,类初始化等几个阶段。)
2. 成员变量的初始化和内存中的运行机制:
? 系统加载类和创建类的时候 1.为成员变量分配空间 2 .指定初始值。
class person
{ public String name ;
public static int eyeNum;
}
{ public class PersonTest{
public static void mian (String [] args){
Person p1 = new Person ;
person p2 = new Person ;
p1.name = “张三” ;
p2.name = “李四” ;
p1.eyeNum = 2 ;
p2.eyeNum = 3 ;
}
}
}
机制:
如第一次使用Person类时系统为类分配内存(堆内存) 并初始化eyeNum的初始值。 系统创建一个Person的实例化对象 name并把对象赋给P1(栈内存中) 变量,而eyeNum不属于Person对象,而是属于 Person类本身,所以没有在创建eyeNum
时候分配给其分配内存。
? 所有Person 的实例访问eyeNum的时候都是访问 Person类中eyeNum的fieldj,
即:访问的是同一片区域.
?
局部变量
1. 局部变量指的是在方法里定义的变量;分为三种: a. 形参:定义方法时定义,作用域在整个方法有效。b. 方法局部变量:方法体内定义的局部变量,方法结束时失效。
2. 局部变量初始化和内存运行机制:
? 局部变量必须显示初始化,系统不会为局部变量执行初始化,即系统定义了局
部变量以后没有为局部变量分配内存,只有在赋值的时候才会为其分配内存。
? 局部变量方法的栈内中,基本变量保存数组,引用类型保存地址。
? 栈中的方法无需系统垃圾回收,往往随着代码块的结束而消失,局部变量占得
内存区比较小。
?
变量的使用规则
1. 成员变量的缺点:变量生存时间变大,导致更大的内存开销;变量的作用域变大,不利于程序的内聚性。
示例:for (int i = 1 ; i <4; i ++){System.out.println(“符合开发规范”);}
int i
for (i = 1; i <5; i++){System.out.println(“不高效”);}
2. 成员变量的作用原则:能用局部变量就不要用成员变量;如果描述的是类或者对象的固有属性则使用成员变量,等。。。
封装
1. 隐藏类的实现细节。
2.
3.
4.
5.
6.
7. 让使用者通过预定的方式来访问数据,从而可以加入逻辑控制,限制不合理访问。 可进行数据检查。 便于修改,提高代码的可维护性。 暴露方法,隐藏细节。 访问修饰符 protect default JAVA 编译 javac ?d . hello.java -d . 代表当前路径 如果不用 ?d 指定编译路径
则编译时 不能产生文件结构。
8. lang (String Math System Thread ) java语言核心系统默认导入
util(List Set Arrays)工具类 集合框架类 接口类
net()网络编程相关接
io()输入输出接口
text()格式化相关的类
sql()JDBC数据库编程相关的类/接口
awt()窗口工具集
swing不解释
构造器 :
1. 创建实例时执行初始化对象,所以一个类必须包含一个或者一个以上的构造器。java默认在无构造器下,提供一个无参数构造器。
2. 构造器可以重载,支持用不同的逻辑去初始化对象,构造器不能被直接调用,用new 调用的构造器会重新创建一个新对象,否则可以使用this关键字创建对象。
3. 构造器初始化以后对所有基本类型默认值为0或者false,对引用类型默认值为null,要改变这种初始化可以显示的赋值。
4. 如果想吧一个类变成最终类,可以使用final修饰这个类。还可以使用private修饰这个类的所有构造器,提供一个静态方法用于创建该类的实例。
5. 构造器,对单个对象初始化,完成整个JAVA对象初始化,然后将java 对象返回给程序。
子类不能继承父类的构造器。
继承
1. java 类只能有一个直接父类。
2. 尽量不要在父类构造器中调用被子类重写的方法。因为在实例化子类的时候会首先实例化父类,并初始化父类的构造器,而父类构造器中的方法时调用子类的,所以造成空指针异常。
组合
初始化块
1. 初始化块只在创建java对象的时隐式执行,初始化块没有名字,也就没有标识,因此无法调用。初始化块在创建对象的时候隐式执行,并且在构造器之前执行。
2. 初始化对象方法 ,构造器,初始化块。
3. java 调用对象时,系统先调用本类的初始化块。普通的初始化块按顺序执行。
4. 普通初始化块,声明实例filed指定的默认值都可以认为是对象的初始化代码,他们的执行顺序与源程序中排列顺序相同。
初始化块和构造器
1. 初始化块总是在构造器之前执行,初始化块不接收参数,对所有对象初始化完全相同且不接受参数,则可以提到初始化块中。
2.
面向对象下
加强封装类(wrapper class )
1. int Integer char character
2. 得到包装类中基本类型变量方法 xxValue () ….如inValue (); 1.5以后加入自动拆箱,自动装箱,只能转化为类型匹配的类。
3. 字符串强转 int a =Integer.paresInt(String s) float f = new float(String s)
5. 简单的将基本类型变为封装类 String a = 5+””(自动转型);
6.封装类可以与数值类型直接进行比较。 封装类实例进行比较时,由于是引用变量只有同时指向同一个对象时才为ture。
7. Integer 4 ==Integer 4 返回 true , Integer 128 = Integer 128 返回false.
原因: 系统将-128~127 之间的整数自动装箱为Integer 实例。放在名为cache 中,所以每次引用的时候都是引用的 cache里的数组,而超出范围就会重新创建实例 所以返回 false.
8.
1. 基本类型:byte 二进制位数:8
2. 包装类:java.lang.Byte
3. 最小值:Byte.MIN_VALUE=-128
4. 最大值:Byte.MAX_VALUE=127
5. (补充)基本类型:short 二进制位数:16
6. 包装类:java.lang.Short
7. 最小值:Short.MIN_VALUE=-32768
8. 最大值:Short.MAX_VALUE=32767
9. 基本类型:int 二进制位数:32
10. 包装类:java.lang.Integer
11. 最小值:Integer.MIN_VALUE=-2147483648
12. 最大值:Integer.MAX_VALUE=2147483647
13. 基本类型:long 二进制位数:64
14. 包装类:java.lang.Long
15. 最小值:Long.MIN_VALUE=-9223372036854775808
16. 最大值:Long.MAX_VALUE=9223372036854775807
17. 基本类型:float 二进制位数:32
18. 包装类:java.lang.Float
19. 最小值:Float.MIN_VALUE=1.4E-45
20. 最大值:Float.MAX_VALUE=3.4028235E38
21. 基本类型:double 二进制位数:64
22. 包装类:java.lang.Double
23. 最小值:Double.MIN_VALUE=4.9E-324
24. 最大值:Double.MAX_VALUE=1.7976931348623157E308
25. 基本类型:char 二进制位数:16
26. 包装类:java.lang.Character
27. 最小值:Character.MIN_VALUE=0
28.最大值:Character.MAX_VALUE=65535
9. 两个boolean 类型的变量比较大小的时候 ture > false;java7 为所有包装类都提供了一个静态方法 compare(type val1 ,type val2 ); 返回值为 0 1 -1.
处理对象
1. String s1 = “ab”+”c”; String s2 = “ab”; String s3 = “c”; String s4 =”abc”; String s5 = s1 + s2 String s6 = new String(“abc”) ;
在编译器就能确定的字符串引用的为常量池中同一个字符串对象存储在栈中。使用new 关
键字创建的对象放在堆内存中。
可重写equals
“==” 用于比较基本常量时候只要数值相同就返回true ,若用来比较引用变量的时候必须指向同一个变量才返回true。
2. 一般情况下 运算符“==” 和 Object默认提供方法“equals”比较结果完全相同都是比较对象的地址 。但是因为String 类中已经重写了equals方法,判断的标准是只要两个字符串包含的序列相等那么就认为两个字符相等。
3. 重写equals 应该具备以下性质:
自反性 : x.equals(x) 返回true
对称性 : 若 y.equals(x) 为true 则 x.equals(y) 为true
一致性,并且对任何不是null 的X值 x.equals 都为false
4.
类成员
static
1. Static 修饰的承运就是类成员,JAVA类成员里只能包含五中类成员:Field ,方法 ,构造器 ,初始化块 ,内部类。
对象不持有类Field . 当使用示例来访问类成员的时候,实际上是委托类来访问方法的,所以如果对象为NULL也可以访问类所属的类成员。
2. 静态初始化块也是属于类的成员,类加载一次静态初始化块也只初始化一次,在下次加载前永远不会再执行。
3. 对static 而言,有一条非常重要的原则:类成员不能访问实例成员。完全有可能出现,类成员加载完成,实例成员没有初始化完成的情况,会引起大量错误。
4. 单例类(一个类始终只能创建一个实力,就叫做单例类)
A、该类的构造器必须为private B、调用方法必须为 static C、使用一个私有静态变量来缓存曾经创建的实例。
对象
实例
法 供外部调用
如:class singleClass { private static singleClass instance ; private singleClass (){}; // 创建一个类变量来缓存// 私有化构造器 防止其他类创建// 提供公用的静态方public static singleClass getInstance (){
If (instance == null ){ } 没有实例则创建实例
singleClass instance = new singleClass(); // 如果 // 添加自定义规则 。。。。。。。。。。。。 return instance ; } } 实例化 singleClass 时候不能直接调用构造器,只能通过调用getInstance方法创建。 Final
1. Final 修饰变量一旦获得初始值就不能再被重新赋值。
2. 如果成员变量没有在定义时给定初始值,也没有在初始化块,构造器中成员变量制定初始值,那么该成员变量的值将一直是系统默认的值,如:0 ,‘\u0000’ ,false , null ,所以JAVA语法规定必须显示地指定 final修饰的变量值,系统不会隐式初始化。
3. Final 局部变量 :系统不会对局部变量初始化,局部变量必须由程序员显示初始化。不能对final 修饰的形参赋值,形参有系统传入的值赋值。
4. Final 修饰基本变量时,不能对基本变量重新赋值。修饰引用变量时只是引用不发生改变但是引用的对象完全可以发生改变。
5. 当final 修饰的变量满足三个条件的时候 该变量就是一个直接量
A、被final 修饰 B、定义时给了初始值 C、该初始值在编译的时候就被确定
6. Final 的一个重要的用途就是定义宏变量,在定义final 的时候就给定初始值,并且在编译的时候就可以被确定,本质上就是一个宏变量,编译器会吧所有用到该变量的地方替换成相对应的值。
如: final String book = “讲义”+521; final String book1 = “讲义”+String.valueof(“521”); System.out.println(“book ==“讲义521”); System.out.println(“book1 ==“讲义521”);
输出结果为:false ,true 。因为book1 中显式的使用了方法将数字转换为字符串。所以在编译的时候不能确
定所以不能被当成宏变量处理,即改字符串没有进入常量池。Book 变量在编译时候可以确定所以被当成宏变
量处理,直接替换,在编译的时候进入常量池。
注:java 会使用常量池管理使用过的字符串,如执行 String a = “word” 之后系统的字符串池中就会缓存一个 word字符串,String b = “word” 时就会直接让b指向常量池中的 word 。 所以指向的是同一个对象。“==”比较
的是左右两边的字符串是否指向同一个对象。
对于宏变量,字符串常量池的理解: String s1 = “javaweb”; String s2 = “java”+“web” String str1 = “web ”; String str2 = “java”; str3 = str1+str2;
System.out.println(s1==s2---str1==str3);//输出true,false,
若将str1,str2改为final 变量则会执行宏替换 ,返回true。
7. Final 方法不可被重写。父类中的private 方法在子类中可以有相同的方法,但不是重写,是两个不同的方法。自然private final
修饰的方法在在子类中也可以有同样的方法,也不是重写。Final 方法可以被重写,不可以被重载。
8. Final 类不能有子类,防止子类重写父类的方法进而对父类中的实现细节和数据进行操作,如:java.lang.Math类。
9. 不可变类的意思是穿件该类的实例以后,实例的filed是不可变的,不可变类包括七大封装类,和java.lang.String类,和自定义不可变类。相对于可变类,该类的实例的filed是可变的。如javabean,里面有大量的get方法。
10. 自定义不可变类的创建规则,A、用private 和fianl 来修饰不可变类的field 。 B、 提供带参构造器,用于初始化类类里的field C、 仅提供get 方法不提供 set 方法。D、有必要时要改写equals方法和hashcode方法。
11. 如果不可变类的引用类型的filed 的类是可变的(引用别的filed),就必须采取措施保护引用类型的filed不会被修改,这样才是不可变类。
(182P 6.4.7 样例)
12. 如果系统中要经常使用相同的不可变量的实例,那么最好的做法就是缓存这个不可变量,可以减少重复创建新的对象见笑系统开销。
13. 用数组来缓存一组不可变量(182p 6.4.8 样例) : 建立一个数组,数组的长度就是缓存池的长度,缓存池满了就进行覆盖,原则是先进先出。
七大基本封装类型的缓存池跟相应内存空间的存储容量有关,比如 Integer 的缓存范围为 -128~127。
抽象类
1. 抽象类不能被实例化,无法使用new 关键字来调用抽象类的构造器来创造抽象类的实例,抽象类的构造器是用来被子类调用的,不是用来创建实例的,抽象方法没有方法体,即没有后面的花括号。
2. 抽象类不能被final , private 修饰 ,抽象方法不能被static修饰。
3. 模板模式,父类不能实现的部分抽象方法留给子类去实现,父类里可以提供通用的方法。
更彻底的抽象:接口
1. 接口里全部是抽象方法;接口是从多个类中抽象出来的规范,不提供任何实现,思想是实现与设计的分离。
2. 接口里定义的常量系统会自动添加 static 和final 来修饰,所以只能在定义时候制定默认值,不管接口里的方法是否显示使用 public abstract 修饰,接口里的方法总是使用public abstract 修饰。
面向接口编程(简单工厂模式):
简单工厂模式思路,在实现接扣时被大量使用的变量与方法剥离,只与接口耦合,这样就可以减少 变量发生改变时的维护成本。
如: public class outputFactory(){
public output getOutput(){ //负责创建 output实例的工厂
return new printer() ;
} public class computer (){ } public void keyIn (String msg){ private output out; public computer(Output out){ } this.out = out; }
//模拟字符串输入的方法
out.getDate();
} public void print(){
} out.out; // 标准输出
}
3.
面向接口编程(命令模式):某方法执行时才知道具体操作,所以必须把“处理行为”作为参数传递进方法。
命令模式思路:将接口作为参数传入到方法中,等调用该方法时才会执行处理行为。 如: public interface command (){ //接口类
void process (int[] target);
}
public class processArry(){
public void process (int[] target, command cmd ){//
确定对数组的具体操作,将操作方法作为参数传递
cmd.process(target);
}
主函数调用此方法,传入参数target ,command 。 具体对数组的操作操作通过实现 command 接口类来操作。(详见6.6.6/198)
通过这种方式来实现 process 方法和过程的分离。
} // 抽象方法
内部类
非静态
1. 内部类的成员可以直接访问外部类的数据,因为内部内是外部类的成员,同一个类的成员之间可以相互访问。
2. 匿名内部类适合于创建仅适用于一次的类,如命令模式中的command对象中的
3. 编译含有内部类的类会产生2个.class文件,一个是类本身,一个是内部类。
4. 非静态内部类可以访问外部类的私有成员,因为在非静态内部类中保存了一个他寄存的类的对象 。
5. 如果外部类变量,内部类变量,和内部类局部变量名字相同可以用关键字 this来区分,this. 调用上一级参数。
静态
1. 静态内部类不能访问外部类的实例成员,只能访问类成员,静态类中可以包含静态成员。
2.
枚举类
1. 枚举类可以实现一个或者多分接口,使用enum 的枚举类继承了java.lang.Eunm类,而不是Object类,实现了Serializable和Comparable两个接口。
2. 使用eunm定义的,非抽象的枚举类默认会使用final修饰,所以无子类,构造器默认使用private修饰符并且只能使用默认修饰符。
3. 枚举类的所有实例必须在该类的第一行显示,并且默认修饰符为public static final 无需显式添加。
4. 所有的枚举类都提供了一个value方法可以遍历所有的枚举值。enum 和 class 用法基本类似。
5. Java.lang.Eunm类中提供了一下几个方法:
int compareTo (E o) :与制定枚举对象比较顺序,之后返回正数,之前返回负数,否则返回0。
String name() : 返回枚举实例名称,建议使用toString.
Int ordinal () : 返回枚举值在类中的索引值,第一个枚举值为0.
String toString() :返回常量名。
对象与垃圾回收
1. 垃圾回收机制值回收堆内存中的对象,不回收任何物理资源,如数据库连接或者IO 等资源。
2. 当对象永久性的失去引用的时候,系统就会在合适的时候进行回收。
3. 在垃圾回收机制回收任何对象之前,总会先调用他的finalize()方法,该方法有可能使对象重新复活,从而取消垃圾回收机制。
4. 当一个对象在堆内存中运行时,可以把他分为三个状态:
可达状态:当一个对象被创建之后,若有一个或者以上变量引用它为可达状态。
可恢复状态:如果某程序对某个对象不在引用则进入可恢复状态,系统在回收之前会调用finalize()方法,如果成功让一个对象引用改变量则恢复可达状态否则进入不可达状态。
5. 强制垃圾回收
方法一,System类的gc()静态方法:System.gc()
方法二,Runtime对象的gc()实例方法:Runtime.getRuntime.gc()
6. finalize() 方法返回后,对象消失,垃圾回收机制开始执行。虚拟机调用finalize()方法时,可能使对象或其他系统中的对象重新变成可达状态。虚拟机执行finalize时抛出异常垃圾回收机制不会告异常,程序继续执行。
7. Finalize为Object 类可以被任何类重写。
8. 对象的强、软、弱、虚引用
StrongReference SoftReference WeakReference PhantomReference
修饰符
1. Public、protect、private、abstrac、final、static、strictfp、synchronized、native、transient、volatile.
JAR文件
1. 全称java archive file .通常为压缩文件,与zip压缩文件兼容。能够对jar文件进行数字签名,值让能够识别数字签名的用户使用里面的东西。通过减少HTTP请求来提高下载速度。
2. jar命令: jar是随JDK自动安装的,在JDK中的bin中。
创建jar包
jar cf test.jar test 将当前目录下的tset 目录下的所有文件打包为 test.ja文件。若文件存在则覆盖源文件。
Jar cvf test.jar test 显示压缩过程
jar cvfM test.jar test 不生成清单文件,因此打包的过程不包含 META-INF/MANIFEST.MF文件,打包过程也略有差别。
(清单文件MANIFEST.MF?)
jar tf test.jar 查看test.jar中的内容
jar tf test.jar > a.txt 由于命令显示行中能显示的行数有限,所以上面方法中如 果文件较多,就不能全部显示。这种方法可以将文件重定向到a.txt(当前目 录中)文件中
jar xf test.jar 解压test.jar文件 jar xvf test.jar 代替是信息解压文件 jar uf test.jar Hello.class 更新test.jar中的Hello.class,若文件存在替换,若不存 在添加。 Jar uvf test.jar Hello.class 带提示信息的解压文件
创建可执行jar包
1. 程序开发完成后大致有三种发布方式:
A 使用平台相关的编译器将整个程序进行编译,生成与平台相关的可执行文件,生成文件丧失跨平台性,性能甚至会有一定程度的下降。
B 为应用编辑一个批处理文件,以windows 操作系统为例,批处理文件中只需要添加如下命令: java.package.MainClass 当用户单击批处理文件时系统就会执行处理文件的java命令,从而运行程序的主类。如果不想保留java程序的命令行窗口,也可在批处理文件中加入如下命令: start javaw package.mainclass
C 将一个程序制作成可执行的JAR包,通过JAR包来发布应用程序。
2. 制作可执行jar包:
1. 在windows下安装jre的时候 ,文件会将*jre文件映射成由javaw.exe打开。创建可执行JAR包的关键在于让Javaw这个命令知道JAR中哪个类是主类。
Jar 命令有个 - e 选项,作用是指定jar包中作为程序入口的主类和类名,因此制作一个可执行的jar包只要增加 -e 就行了,例如:jar cvfe test.jar Test *.test 。这样将所有class 都压缩到test.jar 的jar包下,并使用Trest类作为程序的入口,运行的时候有两种方式。 a. 使用java命令,使用java运行时的语法是 :java -jar test.jar
b. 使用 javaw 命令,使用javaw命令运行语法是:java test.jar
关于jar包的技巧
1. Jar包实际上就是zip文件,所以可以用一般的压缩工具来进行解压,舒勇unzip可以用-d来制定目标目录:unzip test .jar -d test
2.
补充
1. char类型与数字类型的ASCII码值相差48,A ? 65,a ? 115.