`
xinmigo
  • 浏览: 13808 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Core Java 详细解读[1]

阅读更多
1 java优势:跨平台性
虚拟机:java运行时系统,就是一个字节码解释器,虚拟机将字节码解释成机器码给cpu执行.
在java中我们用虚拟机来屏蔽底层操作系统的差异.

编译:生成可执行文件像a.out,a.exe 效率高,但不跨平台
解释:解释器把源文件逐行解释,跨平台但效率不高

在java中:先编译后解释
把.java文件编译成.class字节码文件.(平台中立的) 比重新解释快一点.
由虚拟机解释执行.class字节码文件

jre=虚拟机+编译器
jdk=虚拟机+编译器+类库 //jdk又称java开发工具包


2 第一个程序:
public class Test{
public static void main(String [] args){
System.out.println(“hello world”);
}
}

任何代码都要封装在类里.
一个文件里只能有一个公开类,文件名要和公开类类名一致.如上例文件只能叫Test.java
一个源文件里可以有多个类,一个类生成一个.class文件,.class文件和类对应.
编译:javac +文件名
运行:java+类名
print 打印一行
println:打印一行换行

3 环境变量:
JAVA_HOME:/opt/1.5.06 指向jdk安装目录. 给别的软件用的.
PATH:$JAVA_HOME/bin 一些jdk命令放在bin目录下比如java javac命令
CLASS_PATH:. 类路径,告诉虚拟机去哪找类, 点表示当前路径

4 包:把不同的源文件放在不同目录下.
关键字:package //一个源文件只能有一个package语句.
加了包结构的类编译时javac –d . Test.java会自动生成目录结构,点表当前目录,前后都有空格.
运行时要写全限定名: 包名.类名 java p1.HelloWorld
运行时要在包的上一级目录

5 import:是一个声明 后面遇到类名可以不写包名.
import p6.p7.*;表示以后用p6包下的p7子包下的所有类不用在写包结构了.
import只能表示类,不能表示子包

java.lang.* 这个包下的类是默认引入的.
一个类里可以有0个或多个import,跟c++里的include不一样

6 注释
//单行注释 到本行结束的所有字符会被编译器忽略.
/* */ 多行注释 在/* */之间的所有字符会被编译器忽略.
/** */ 文档注释 java特有的, 在/** */之间的所有字符会被编译器忽略.
javadoc 工具,把java源程序中这种注释抽取出来形成html页面.
javadoc –d doc Tarena.java

7 标识符命名规则:包括包名,类名,属性名,方法名等等
(1) 由字母,数字,下划线,$组成,不能以数字开头.
(2) 大小写敏感.
(3) 不得使用java中的关键字和保留字.

关键字:都是小写的 jdk1.4多了 assert关键字 jdk1.5多了enum 关键字
保留字:goto 和const
字面值:true 和false 是boolean类型字面值

习惯:

(1) 标识符要符合语义信息.
(2) 包名所有字母小写
(3) 类名每个单词首字母大写,其它小写 //TarenaStudent
(4) 变量和方法: 第一个单词小写,从第二个单词开始首字母大写 //tarenaStudent
(5) 常量: 所有字母大写

8 局部变量:定义在方法里的变量.
(1)必须要先赋值,后使用.用之前要初始化,否则通不过编译.
(2)作用范围:定义开始到定义它的代码块结束.
(3)重合范围内,不允许2个局部变量命名冲突.

9 java中的数据类型:基本数据类型和对象类型

基本类型:8种 与整型有关的前4种
(1) byte 1B -128-127
(2) short 2B -32768-32767
(3) int 4B -2147483648-2147483647
(4) long 8B 加后缀L 赋给long类型变量
(5) float 4B 加后缀f
(6) double 8B 加后缀d 或不跟
(7) boolean 1B 字面值 true 和false //整数和boolean值不能相互转换了.
(8) char 2B 采用unicode编码方式.全球统一的字符集. // char c='达'; 可以保存汉字

任何国家编码方式都兼容ASCII编码, 编码方式和解码方式不同才会出现乱码.
char类型的三种字面值.
char c='a';
char c= 97;
char c='\u0061'; //unicode 码值是用16进制表示的,一个字节可以用2个16进制表示

byte a=1;
byte b=2;
byte c=a+b; //编译出错自动类型提升成int

自动类型提升,把高字节转成低字节,需要作强制类型转换. byte c=(byte)a+b;


类型自动提升规则:
a和b作某种运算
a和b中有double,结果就是double
a和b中有float,结果就是float
a和b中有long,结果就是long
除此之外,结果都是int

对象类型: String
java中一个字符串是一个对象.这个对象有字面值,java中内置重载了+号,表示字符串的连接
String s=”abcd” //双引号引起来
"1"+2+3 结果 "123"
1+2+"3" 结果 "33"

int x=1;
int y=2;
System.out.println(x+"+"+y+"="+(x+y));

10 运算符:
byte a=20;
a+=10; //自加没有自动类型提升问题
a=a+10;

>> 有符号右移,补符号位
>>> 右移后高位都补0;

a1=1000;
System.out.println(a1>>1); a1=500
System.out.println(a1>>1); a1=500
a2= -1000;
System.out.println(a2>>1); a2= -500;
System.out.println(a2>>1); a2=214553;

5/2=2 //整数除整数是整数
5.0/2=2.5

11 程序流程控制:
if else: 和c++的区别就在条件语句if(true)
switch(byte short int char) //必须是整形兼容的

循环:
for(int i=0;i<=10;i++){语句块} //知道循环次数时使用
while (条件){语句块} //不知道循环次数时使用
do{语句块} while(条件) //至少执行一次
------------------------------------------------------------
1 数组:
内存中一块连续的存储空间, 一个数组是一个对象,一次定义多个同类型变量.

int [] a; //定义数组,常把a写后面,a不是整型,是个整型数组
a=new int[10]; //new 关键字,分配空间, 指定大小,首地址记录在a里,java里不允许操作指针.
a.length //数组对象没有方法,只有一个属性. 用length表示数组长度.

数组元素默认值规则:数组用new给分配空间时,默认赋值各种各样的0.

long 0L
double: 0.0d
float: 0.0f
char:'\u0000'
boolean: false
String: null

2 显示初始化:
int [] a= {1,2,3,4,5,6,7} //[]里不能写数, 数组长度一旦确定不能改变

3 二维数组:
一维数组的一维数组,每行又是一个一维数组.

int [3][4] a //三行四列
int[][] b=new int[][3]; //error!! 因为列的元素有可能是不确定的,如下例

int [][] b=new int[3][]; //java中特有的

b[0]=new int[3]; 0 0 0 //初始值
b[1]=new int[4]; 0 0 0 0
b[2]=new int[2]; 0 0

遍历二维数组:

for(int i=0;i<b.length;i++){
for(int j=0;j<b[i].length;j++){ // 把二维数组看成一维数组的一维数组.
System.out.print(b[i][j]+"\t");
}
}

4 什么是对象:
everything is object. 只要这个东西客观存在,看不见的对象不表示该对象不存在,比如错误,事件等都是对象.

对象有属性和方法:
属性:有什么
方法:能做什么

5 什么是面向对象:
符合客观世界一般规律,用现实的方法解决计算机问题.
面向对象是一种思想,不是谁发明的,是人们归纳了客观世界.

面向对象的要求:
(1)各司其职,各尽所能,简单才专业
(2)弱耦合性(标准):系统中对象和对象的联系应该尽量的弱.
(3)可重用性: 对象的功能越简单其可重用性越高.
(4)可扩展性

面向过程:先有算法,后有数据结构,先考虑怎么做
面向对象:先有数据结构,后有算法,先考虑用什么做

6 类是一类事物的共性,是人类主观认识的一种抽象,是对象的模板.
7 实例变量:定义在类里的变量
(1)允许命名冲突,以局部变量为准(局部优先).
(2)不需要初始化
(3)作用范围:最小范围是类内部

8 在java中,声明就是定义,定义就是声明.
声明或定义一个方法五部分:

修饰符 返回值 方法名(参数表) 抛出的异常{实现}

(1) 修饰符 顺序可以掉换 public static 或static public
(2) 返回值 没有返回值void
(3) 方法名
(4) 参数表: 可以0或多个,逗号隔开
(5) 抛出的异常

9 方法的重载(overload):
编译时多态,在一个类里的方法,类名相同,参数表不同,
凡类型,个数,顺序不同都是参数表不同,重载与返回值类型无关,只与参数有关.

调哪一个是编译器在编译时决定的.

方法重载作用:对于同类方法,由于参数不同会有差异,这种差异对对象的使用者屏蔽.
对象的使用者只负责把参数交给对象,而具体怎么实现由对象自己处理.

System.out.println(12);
System.out.println(“hello”);
-----------------------------------------------------------------
面向对象
对象:客观存在的就是对象.考察对象有两方面
属性:有什么.
方法:能做什么.
符合我们看待客观世界的规律.
各司其职,各尽所能,弱耦合性,可复用性,可扩展性.
方法的重载:向上就近匹配原则,必须要明确引用.

1 构造方法:
构造对象时要调用的方法.是创建对象的一个必不可少的工序.

特点: (1) 无返回值类型
(2) 方法名与类名相同

默认的构造方法是空的,无参的.习惯:给类加无参构造方法.
A a=new A(); a:对象的引用,存放对象的地址

功能: 更多用来初始化属性.不能手工调用.在对象生命周期内只能调一次.

java中没有析构方法.

2 java中的自动回收机制垃圾回收器:
我们可以不用顾虑对象创建后占用系统资源的问题.我们只 负责对象的创建,而对象销毁和资源释放的问题就可以留给垃圾回收器去做,要注意垃圾回收器 只会在内存空间不够的情况下进行资源回收.这样效率会高.

3 构造对象过程:
(1) 分配空间 new+类名() 默认值0
(2) 初始化属性
(3) 调用构造方法

4 参数传递规则:
简单类型的参数传值,对象类型的参数传引用

5 声明:
Student s,这时我们只是说明s是一个能够指向Student类型的引用(对象变量),
并没有创建一个对象。所以我们不能对s做任何操作.

初始化:s = new Student(); 向系统申请一块存储空间(地址空间),该地址空间保存的是
一个Student类型的数据。而s中保存的就是该地址空间的首地址。

一个对象可以有多个引用指向。

Student[] s = new Student[3] //相当于声明一个长度为3的Student类型的数组。


6 对象和对象引用的区别:
对象好比一台电视机,对象引用好比电视机遥控。对象引用中存的是对 象的地址。多个对象引用中存放的是同一个地址,表示该对象被多个对象引用所引用。

7 this关键字:
this:是个引用,表示当前对象,要注意区分谁是当前对象,
功能:可以区分开局部变量和实例变量的命名冲突.
this()可以调用本类中其它的构造方法,必须放在构造方法的第一行.

8 面向对象三大特性:封装,继承,多态
(1)封装: 该隐藏的隐藏,该公开的公开 属性是私有的要隐藏起来,更安全

对于属性: 要提供获取和设置属性的方法:
getAge(); 获取属性
setAge(); 设置属性

对于方法: 该隐藏的隐藏,该公开的公开(给自己用的隐藏,expand()扩充)
声明 公开 能作什么
实现 隐藏 怎么做 这样使得实现的改变对架构的影响最小.

隐藏的目的:实现的改变对架构的影响最小.

封装的好处: 安全,弱耦合

(2)继承:

java特点:泛化:从子类中抽象出共性放在父类,得到父类的过程.
特化:先有类父类,在有了子类.把子类放在类继承关系树中.

java中单继承,一个类只有一个直接父类.

单继承是java简单性的体现:树状结构比网状结构简单.

共性属父类是弱耦合性的体现.
--------------------------------------------------------------------
1 继承:

(1) 父类到子类是从一般到特殊的关系.
(2) 继承的关键字:extends
(3) java中只允许单继承,父子类之间是树状关系.
(4) java中习惯上说private属性不能继承.
(5) 原则:共性放在父类,个性放在子类.
(6) 构造方法不能继承.如果在子类父类构造方法算个普通方法它没有返回值类型
如果在子类父类构造方法算个构造方法它和子类类名又不相同.

2 访问属性和继承关系:

访问属性从严到宽 继承关系

private: 仅本类成员可见 不能继承
default: 本类+同包类可见 不一定能继承
protected: 本类+同包+不同包的子类 能继承
public: 公开 能继承

3 带继承关系的对象创建的过程:

(1) 分配空间
(2) 递归的构造父类对象
(3) 初始化属性
(4) 调用构造方法

例: C继承B,B继承A;

调用过程: 分配空间->初始化A 属性->A()->初始化B属性->B()->初始化C属性->C()
默认会调父类无参构造方法.如果父类没有无参构造方法会报错.
所以养成写无参构造方法好习惯

4 继承复用和组合复用:组合/聚合复用原则

class Liucy{
public void teachCpp(){
System.out.println("Teach C++");
}
public void teachUC(){}
public void chiMoGu(){}
}
class Huxz1 extends Liucy{}

应该用组合/聚合复用去代替继承关系的复用.
class Huxz2{
private Liucy liucy=new Liucy(); //把一个对象作为自己的属性,自己的一部分

public void teachCpp(){
liucy.teachCpp();
}
public void teachUC(){
liucy.teachUC();
}
}




5 super关键字:

也是个引用,指向父类对象.
作用:区分本类属性和父类被遮盖的属性.
区分本类的方法和父类被覆盖的方法.

super() 调用父类的构造方法.
在子类的构造方法中如果没有指定调用父类的哪一个构造方法,
那么就会调用父类的无参构造方法,即super()

super() 也和this一样必须放在方法的第一行第一句。
super(). 表示调用父类的方法或属性。例:super.m();

6 覆盖和重载

父子类中也能重载,而且不隐藏
方法覆盖(override):覆盖的是实现,是子类用自己的实现覆盖调父类的实现.
覆盖的语法: 方法名相同,参数表相同.返回值要相同.
修饰符要求子类与父类相同或比父类更宽,抛出的异常也有限制,以后在说.
辨别重载和覆盖看参数表.

7 多态:

引用类型:编译时类型,
new 运行时类型
运行时类型是编译时类型的子类.

多态原则: (1)对象不变,运行时类型不变
(2)只能对一个对象调用其编译时类型定义的方法
(3)运行时会根据对象的运行时类型找覆盖之后的方法.

Animal a=new Dog();
Dog d=a; //编译时出错 不兼容类型
Dog d=(Dog) a; //认为有可能对的情况才会通过编译
Animal b=new Cat();

父类的引用赋值给子类的引用需要强转.
子类的引用赋值给父类的引用不需要强转.

8 运算符instanceof :
用法:引用 instanceof 类名 用处:判断该引用与所指向的那个对象是否兼容.
是返回true 不是返回false.一般用在强制类型转换之前.

多态作用: 可以屏蔽不同子类的差异,统一把他们当作父类看待
----------------------------------------------------
多态:可以把一个子类对象当做一个父类对象看,只能调用父类中有的属性和方法.
如果子类覆盖了父类的方法,那么把子类对象当父类看时,调用子类覆盖后的方法.

Animal() eat()
| |
狮子 马
eat() 吃肉 eat()吃草

左边:把它当什么看,右边:对象本身

什么时候可以强转:认为有可能强转时才能转.
Animal a=new Dog();
Dog d=a; //编译时出错不兼容类型
Dog d=(Dog) a; //认为有可能对的情况才会通过编译
Animal b=new Cat();

instanceof 是用于判断一个对象是否属于某个类型,常用在强制类型转换之前.

1 static 修饰符:

static:静态的,可以修饰:
(1)属性:静态属性,全类公有,常叫做类变量,和具体对象无关,无多态,类名去访问,类加载的时 候初始化,像动物园动物个数.不是某个具体对象的行为.

(2)方法:静态方法中只能访问类的静态成员(包括静态属性和静态方法),非静态方法中可以
问静态方法的属性和成员. 工具类的对象都是static的 (java.math就是工具类)

(3)代码块注:初始代码块是在类中而不再任何方法之内的代码块。被static修饰的代码块称静 态代码块,静态初始代码块在类加载的时候运行一次.

2 变量:

局部变量
实例变量 非静态 属性
类变量 静态 属性

3 类加载:虚拟机从磁盘上将字节码文件中的内容通过I/O流读到内存的过程。在虚拟机的生命周 期中一个类只被加载一次,什么时候加载什么时候运行。类的对象在类加载的时候被创建. 注: Java命令的作用是启动JVM。

4 final修饰符,可以修饰:

(1)属性:表示这个属性的值不可变. 例:身份证号 赋值时间两种:
在定义时赋值,一般和static合用,不加也相当于static, 加上static省空间
在构造方法中赋值,每个对象的值可以不一样.但值给定了,就不能变.

(2)方法:表示这个方法不能被覆盖

(3)类:表示这个类不能被继承.

(4)方法中的局部变量:局部变量值不可变,常量.

5 abstract: 抽象的,可以修饰:

(1)方法:只有定义,没有实现, public abstract void move(); //用分号代替一对大括号
(2) 类:含抽象方法的类必须是抽象类,但抽象类不一定含抽象方法.

抽象类不能实例化,即不能构造对象不能new. Animal a1 =new Animal() //error!!!
抽象类可以定义引用.让子类覆盖,抽象类作用,就是让子类继承.构造方法不能抽象.

注意:abstract不能和final 合用

6 接口 interface:一个特殊的抽象类

不能说继承,而说实现接口,关键字:implements
接口里的属性都是公开静态的属性;方法都是公开的抽象方法.接口没有构造方法.

例1: abstract class Myclass{ 例2: interface IA{
public static final int A=10; int A=10;
public static final int B=20; int B=20;
public abstract void m1(); void m1();
public abstract void m2(); void m2();
} }
例1 和 例2 是等价的.

接口和接口间存在继承关系,接口之间可以多继承,之间用逗号隔开.
一个类在继承另外一个类时还可以实现接口,要先写继承后写实现.

类 extends类
类 implements接口
接口 extends接口

把接口当成功能模块,标准
标准的制定者和标准的实现者分开.

7 对象相等判断:equals方法
写equals方法原则:

(1) 满足自反性 a.equals(a) 必须为真
(2) 传递性 a.equals(b) b.equals(c) -> a.equals(c) 为真
(3) 对称性 a.equals(b) 为真, 那么b.equals(a) 为真
(4) 一致性 对象属性不改变时,返回值要一致.
---------------------------------------------------------
1 接口:定义接口关键字interface,接口是一种特殊的抽象类
接口中的所有方法默认都是public abstract方法
接口中的所有属性默认都是public static final的属性

2 一个类可以实现多个接口class A implements interfaceIA,interfaceIB
所谓实现一个接口就是实现接口里定义所有的方法,关键字implements
接口的父类不能是类. interfaceIA extends classA !!!error


3 子类 父类

接口 类 !error
接口 接口 多继承 关键字extends
类 类 单继承
类 接口 implements接口

4 接口中没有构造方法.

5 泛化:由子类抽象出父类的过程
特化:由父类扩展出子类的过程

6 接口作用:把标准的制定者和标准的实现者分离,易于可扩展性和可移植性.
接口回调:先有接口的定义,再有接口的使用者,最后把接口的实现者传到接口的使用者中,
接口的使用者会通过接口来调用接口实现者的方法。

public class TestJDBC {
public static void main(String []args){
Driver d=getDriver(args[0]);
d.connect();
}
static Driver getDriver(String name){
if(name.equals("MySQL")) return new MySQLDriver();
else if(name.equals("DB2")) return new DB2Driver();
else return new OracleDriver();
}
}
interface Driver{
void connect();
}
class MySQLDriver implements Driver{
public void connect() {
System.out.println("connected MySQLDriver");
}
}

class DB2Driver implements Driver{
public void connect() {
System.out.println("connected DB2Driver");
}
}

class OracleDriver implements Driver{
public void connect() {
System.out.println("connected OracleDriver");
}
}

7 注意点:
(1)一个文件只能有一个public接口,且与文件名相同.
(2)在一个文件中不能同时定义一个public接口和一个public类.
(3)接口与类之间只有实现关系,没有继承关系.
(4)抽象类与类之间只有继承关系没有实现关系.
(5)接口与接口之间只有继承关系,且允许多继承.
(6)接口中可以不写public,但在子类实现接口的过程中public不可省略.

8 接口和抽象类
(1)接口中不能有具体的实现,但抽象类可以。
(2)一个类要实现一个接口必须实现其里面所有的方法,而抽象类不必。
(3)通过接口可以实现多继承,而抽象类做不到。
(4)接口不能有构造方法,而抽象类可以。
(5)实体类与接口之间只有实现关系,而实体类与抽象类只有继承关系。

9 修饰符 类 属性 方法 局部变量

final * * * *
static * *
abstract * *
public * * *
protected * *
default * * *
private * *

10 ==和equals的区别

基本类型用==去比较比的是值是否相等.
如果是对象用==比是两个引用中的地址值是否相等
判断两对象内容是否相等时用equals()方法,equals 比较两个对象内容是否相等.

11 toString()方法:给出这个对象的字符串表达形式,返回一个字符串.
当直接打印出对象的引用,它实际输出的是这个对象的toString()方法的返回值.
Student s1=new Student();
System.out.println(s1); // toStrint()方法的返回值

Object类toString()方法返回值两部分: 包名加类名@地址 day5.Student@757aef
在java里只能用这个方法来看对象的地址,但只能看,不能操作这个地址.

字符串相加时,也会去调toStirng()方法,"hello"+str1.

12 主方法的参数:字符串数组argv java Test argv[0]
//与c++不同,命令行第三个元素才是数组的第一个元素
主方法是程序的入口,主方法必须声明为静态的.


13字符串赋值形式:

String s1=new String("haha"); //新开辟空间,生成一个新的字符串对象.
String s2="haha"; //在串池找

int a=5;
int b=a<<33;
System.out.println(b); //结果b=10,移位运算时系统会对32求余

14 对于字符串:
(1)对象池
(2)不变模式: 生命周期内值不变, String s1=new String("Hello");
一个字符串实际是用一个字符数组来作底层的保存空间,所以不可改变值.

在需要频繁改变字符串值时建议用StringBuffer() 可以改变值,不创建新对象

15 基本类型的包装类.把基本类型包装成相应的类类型.符合一切皆对象的天理.
八种,保留基本类型效率高.

除了int 和char,其余类型首字母大写即成包装类
int Integer
char Character

int Integer String之间的类型转换(最常用的)
int a =12;
int 到 Integer Integer aa = new Integer(a);
Integer 到 int int i = aa.intValue();
Int 到 String String str = String.valueOf(i);
String 到 int int ii = Integer.parseInt(str);
Integer 到 String String str = aa.toString();
String 到 Integer Integer bb = Integer.valueOf(str);

int a=20;
String s=a+""; //加空串也可以得到一个字符串.
-------------------------------------------------------------------
在主方法中:return; 和 System.exit(0); 等同


内部类:(课堂代码:InnerClassTestA.java)
在一个类的内部定义的类称为内部类。内部类是一种编译时的语法。
编译时语法:内部类,访问权限,泛型

内部类存在的原因:在现实世界中有这样的需要。在内部类可以访问外部类的私有属性。内部类可以对同一个包中的其他类隐藏起来。
所有使用内部类的地方都可以不用内部类,但使用内部类可以使程序更加的简洁,便于命名规范和划分层次结构

内部类的作用:1、内部类可以访问外部类的私有成员
2、把标准公开,把标准的实现者作为内部类隐藏起来,强制要求使用者通过标准访问标准的实现者
3、配合接口,实现多继承
当父类和接口方法定义发生冲突的时候,就必须借助内部类来区分
内部类的分类:
成员式:
静态内部类:

在静态内部类中只能访问外部类的静态成员。构造静态内部类对象不再需要构造外部类对象

成员内部类:
必须要先构造外部类对象,再根据外部类对象构造内部类对象。
生成成员内部类对象形式: OuterA out=new OuterA();
OuterA.InnerB innb=out.new InnerB();
一个外部类对象可以生成多个成员内部类对象,一个成员内部类对象一定是由某一个外部类对象生成的。
成员内部类不能有静态属性

内部类和外部类的实例变量可以共存。
在内部类中访问实例变量:this.属性
在内部类访问外部类的实例变量:外部类名.this.属性。

局部式:
局部内部类:定义在外部类的方法中。
与局部变量类似,在局部内部类前不加修饰符public和private,其范围为定义它的代码块。

局部内部类不仅可以访问外部类实例变量,还可以访问外部类的局部常量,但是要求外部类的局部变量是final的。
实际上是为内部类添加了一个属性,这个属性就是外部类的final局部变量
在类外不可直接访问局部内部类(保证局部内部类对外是不可见的)。
在方法中才能调用其局部内部类。

匿名内部类: 特殊的局部内部类,用来继承一个类或者实现一个接口,我们只需要这个局部内部类的一个对象。
匿名内部类不能定义构造方法
匿名内部类在编译的时候由系统自动起名Out$1.class。
如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。
因为匿名内部类无构造方法,所以其使用范围非常的有限。

java.util.GregorianCalendar中的月份从0开始,周日是一周的第一天
-----------------------------------------------------------------
数组:固定长度

集合框架

集合(集合类的对象)是用来管理其他若干对象的。它类似于C++标准模板库中的容器,不过在JAVA的集合类的对象中可以用来存放多种类型的对象。

接口和类共同构成了一个集合框架,集合的概念,一个对象可以装载多个对象,这个对象就是集合对象。


1,接口
Collection

|ˉˉˉˉˉˉ|
Set List Map
↑ ↑
| |
SortedSet SortedMap


集合中用到的类,接口在java.util包中,在使用时注意将其引入import。

Collection 接口: 用来管理多个对象,集合中的每个元素都是对象。

1)List接口: 一个List的实现类的对象在管理多个对象时会按顺序组织对象(即按照将对象放入的顺序存储)

List实现类的对象是有顺序的,List实现类对象中的内容是可重复的。(注意,顺序和排序的区别)

List接口的特点:有序存放,允许重复,可放不同类型对象

2)Set接口: 一个Set的实现类表示一个数学概念上的集合,Set的实现类的对象中的元素是无顺序的,也就是不会按照输入顺序来存放,
Set的实现类对象中的元素是不重复的。

Set接口的特点:无序存放,不允许重复,也可以存放不同类型对象

3)SortedSet接口:它是Set的子接口,他的实现类会对集合中的元素进行排序。但是要指定排序规则,他会按排序规则进行排序。


Map,Map中没有对象,而是键值对,由Key,value组成的键值对
Key是没有顺序,不可重复的。
value是可以相同的,一个Key和一个value一一对应。

Map 接口(以下介绍其子接口)

SortedMap,这个接口的实现类同样可以实现,不过是对键值对中的Key进行排序,这个接口的实现类也是要指定排序规则的


2、List接口的实现类

Collection

|ˉˉˉˉˉˉ|
HashSet LinkedList Hashtable
(Set) Vector, ArrayList Hashmap
(List) (Map)
↑ ↑
| |
TreeSet TreeMap
(SortedSet) (SortedMap)


Collection接口的方法:
add(Object o)
addAll(Collection c)
contains(Object o)
containsAll(Collection c)
remove(Object o)
removeAll(Collection c)
clear()
equals(Object o)
isEmpty()
iterator()
size()
toArray()
toArray(Object[] o)


Iterator it=hs.iterator();
for(Object obj;it.hasNext();){
obj=it.next();
...
System.out.println(obj);
}


1> ArrayList是接近于功能的集合类,ArryList的实质就是一个会自动增长的数组,ArrayList是用封装的数组来实现的List接口的,底层用数组实现的。

Collection的实现类对象的遍历方式是用迭代来实现的。
在使用迭代器时先要获得一个迭代器的对象,Iterator(迭代器接口)这是一个接口,迭代器是在集合类中实现的,
也就是说,他是一个内部类(匿名内部类)实现的。
Iterator接口中定义的常用方法方法hasNext(),next()。
hasNext(),这个方法会使用一个游标,并通过判断游标指向的位置是否存放有对象。
next()方法也是Iterator接口中定义好的方法,这个方法会使游标指向下一个元素的位置,游标会跳过第一个元素,并返回其中的内容。

Collections 这是一个工具类,也是java.util包中的,这个类中的sort(list接口的实现类的对象)方法,其参数是一个集合类的对象,
这个方法使用来对集合类的对象进行排序的。以后,我将以集合这个名字来称呼集合类的对象。对于字符串对象内容的集合来说会按字典顺序排序(升序),
对于数字内容的集合排序也会按照升序排序。

排序可分为两部分内容,一个是排序的规则,也就是按照什么来进行排序,并且排成什么样的顺序。
第二个就是排序的算法,他决定了排序的效率。

在对自定义的集合内容类型排序时,需要先定义那个类型的排序规则。
Comparable接口,这个接口中只定义了一个compareTo(Object o),方法的返回至类型是整型,如果当前对象大于参数对象就返回正数,当前对象等于参数对象 是就返回0,当前对象小于参数对象时就返回负值,这样写就是升序排列,反之则是进行降序排列,在实现这个接口中的方法时,返回值定义方式,只有这两种

根据指定类型的排序规则实现了Comparable接口,那么就可以对存有这个类型的集合进行整体排序。Comparable接口,也叫做可比较接口。
这个接口在java.lang包下。只要实现了这个接口,就是可排序的。

接下来介绍另外一种对自定义类型对象的集合整体排序的方法,也就是实现比较器接口(Comparator),
这个接口中定义了一个compare(Object o1,Object o2)方法来比较两个对象,这个方法的返回值定义和上面介绍的那个方法是一样。

注意:在API,帮助文档中以上两个方法的参数类型是T,这代表的模板类型,也就是集合中存放的内容的类型,在JDK1.4中其参数就是Object类型,
模板类型的详细内容会在最后的JDK5.0新特性中讲到。

Comparator接口可以在匿名内部类中实现,Collections 中的sort(集合了的对象,比较器)方法,可以对自定义类型内容的集合进行整体排序。

2> LinkedList,它是List接口的实现类,其底层是用双向循环链表来实现的。

注意:ArrayList的查询效率比较高,增删动作的效率比较差,适用于查询比较频繁,增删动作较少的元素管理的集合。
LinkedList的查询效率低,但是增删效率很高。适用于增删动作的比较频繁,查询次数较少的元素管理集合。

ArrayList,LinkedList都是线程不安全的。

3> Vector: 底层用数组实现List接口的另一个类
特点:重量级,占据更多的系统开销 线程安全
(与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。)
结论:在考虑并发的情况下用Vector(保证线程的安全)。
在不考虑并发的情况下用ArrayList(不能保证线程的安全)。

面试经验(知识点):
java.util.stack(stack即为堆栈)的父类为Vector。可是stack的父类是最不应该为Vector的。因为Vector的底层是数组,
且Vector有get方法(意味着它可能访问到并不属于最后一个位置元素的其他元素,很不安全)。
对于堆栈和队列只能用push类和get类。
Stack类以后不要轻易使用。
实现栈一定要用LinkedList。


实现堆栈 1,数组(ArrayList,增删效率比较低,不适合)
2,LinkedList(实现堆栈的好方法)
3,java.util.Stack类,Stack是Vector的子类,Vector类是一个线程安全的(是一个重量级的类),并继承了Vector的方法,
Verctor类和ArrayList的功能近乎相同。(不推荐使用Stack类来实现堆栈)。



3、Set接口的实现类

3.1 HashSet

Set的实现类的集合对象中不能够有重复元素,HashSet也一样他是使用了一种标识来确定元素的不重复,HashSet用一种算法来保证HashSet中的元素是不重复的, HashSet采用哈希算法,底层用数组存储数据。默认初始化容量16,加载因子0.75

Object类中的hashCode()的方法是所有子类都会继承这个方法,这个方法会用Hash算法算出一个Hash(哈希)码值返回,HashSet会用Hash码值去和数组长度取模,
模(这个模就是对象要存放在数组中的位置)相同时才会判断数组中的元素和要加入的对象的内容是否相同,如果不同才会添加进去。

Hash算法是一种散列算法。

Set hs=new HashSet();

hs.add(o);
|
o.hashCode();
|
o%当前总容量 (0--15)
|
| 不发生冲突
是否发生冲突-----------------直接存放
|
| 发生冲突
| 假(不相等)
o1.equals(o2)-------------------找一个空位添加
|
| 是(相等)
不添加

覆盖hashCode()方法的原则:
1、一定要让那些我们认为相同的对象返回相同的hashCode值
2、尽量让那些我们认为不同的对象返回不同的hashCode值
3、尽量的让hashCode值散列开(两值用异或运算可使结果的范围更广)


注意:所以要存入HashSet的集合对象中的自定义类必须覆盖hashCode(),equals()两个方法,才能保证集合中元素不重复。在覆盖equals()和hashCode()方法时,
要使相同对象的hashCode()方法返回相同值,覆盖equals()方法再判断其内容。为了保证效率,所以在覆盖hashCode()方法时,
也要尽量使不同对象尽量返回不同的Hash码值。

如果数组中的元素和要加入的对象的hashCode()返回了相同的Hash值(相同对象),才会用equals()方法来判断两个对象的内容是否相同。

3.2 SortedSet接口是Set的子接口。TreeSet是SortedSet接口的实现类

TreeSet底层用二叉树实现。它可以对集合中的元素进行排序。
要存放在TreeSet中自定义类的对象,这个类要么是已经实现了Comparable接口,要么是能给出Comparator比较器,
TreeSet可以自动过滤掉重复元素所以不用重载hashCode()方法,TreeSet会根据比较规则判断元素内容是否相同,TreeSet会在元素存入时就进行了排序。
(在TreeSet给出排序规则时,一定要注意对象内容相等的条件,一定要注意在主观的认为两个对象内容相同时,才可以使用比较少的条件来进行判断)

在要排序时才使用TreeSet类(存储效率比较低),HashSet的,,存储效率比较高,在需要为HashSet的对象排序时,就可以把HashSet中的元素放入TreeSet。



Iterator:迭代器 java.util
Iterable:可迭代的 java.lang

Comparator:比较器 java.util
Comparable:可比较的 java.lang
-------------------------------------------------------------
List:
1、有序的
2、允许重复
3、不同类型的对象
Set:
1、无序的
2、不允许重复
3、不同类型的对象

SortedSet (TreeSet):
1、排好序的集合
2、不允许重复(值相等的对象)
3、同类型对象,能比较大小

Map:
Map中只可以存放键值对(Key,value),其中Key是不可以重复的。Key和value是一一对应的。

HashMap,是Map接口的实现类,Key时无序存放的,其中Key是不可以重复的,它也是通过Hash码值来保证Key不重复的,Key和value是一一对应的。
如果要加入的键值对和HashMap中键值对的Key是相同的就会将这个集合中的Key所队应的value值进行覆盖,
在使用自定义类型作为Key时,那就是要覆盖hashCode(),equals()方法,也就是和HashSet中要放入自定义类型是的处理方法相同。
这个类的对象是线程不安全的。

查找:boolean containsKey(Object key) 如果此映射包含指定键的映射关系,则返回 true。key 测试在此映射中是否存在的键。
boolean containsValue(Object value)如果此映射为指定值映射一个或多个键,则返回 true。

添 加:V put(K key,V value)
void putAll(Map<? extends K,? extends V> t)从指定映射中将所有映射关系复制到此映射中(可选操作)。

遍历:(1)vlaues() 返回所有值(value)的集合,是一个Collection
(2)keySet() 返回所有键对象的集合,是一个Set,遍历这个Set,用get()方法来获得Key所对应的value,也就遍历了Map。

删除:V remove(Object key)

Hashtable,也是Map接口的实现类,他和HashMap比较相似,只不过这个类对象是重量级的,也是线程安全的。他不允许Key和value为null。

Properties,这个类是Hashtable的子类,他的Key和value只能是字符串。

SortedMap是Map的子接口
TreeMap,是SortedMap的实现类,他会按照Key进行排序。和TreeSet类一样,在使用自定义类作Key时,要用自定义类实现Comparable接口。


反射:

用于工具,架构,动态开发等开发工程
三种得到类对象的途径:
Class.forName(“name”) //输入全类名 Class c1=Class.forName("Student");
object.class //Class c2=Student.class;
object.getClass() //得到该对象的类对象 Class c3=stu1.getClass(); stu1是Student对象

无参构造一个对象 newInstance()
有参的构造一个对象 Constructor con=c.getConstructor(String.class); Object o=con.newInstance(“liucy”);


调用对象方法
Class newClass=Student.class; //得到一个类对象
Object o = newClass.newInstance(); //产生对象
Method newMethod = newClass.getDeclaredMethod("study");//得到这个类的方法类
newMethod.invoke(o);//调用方法,需要提供是哪个对象调用和参数

1) 确定一个对象的类;
2) 获得一个类的修改符、变量、方法、构器函数、和父类的相类信息;
3) 找出哪些常量和方法是从一个接口声明的;
4) 创建一个在运行时才知道名称的类;
5) 调用对象的方法;

public Method getDeclaredMethod(String name,Class... parameterTypes) Class...parameterTypes 是可变长参数

Class类 java.lang

方法 功能 返回值

c.getPackage() 包 Package
c.getSuperclass() 父类 Class
c.getModifiers() 修饰符 int
c.getInterfaces() 接口 Class[]
c.getDeclaredFields() 属性 Field[]
c.getDeclaredMethods() 方法 Method[]
c.getDeclaredConstructors() 构造器 Constructor[]


Field: 方法 返回值
getModifiers() int
getType() Class
getName() String
get(Object obj) Object
set(Object obj,Object value) void

Method: 方法
getModifiers() int
getReturnType() Class
getName() String
getParameterTypes() Class[]
invoke(Object obj,Object... args) Object

Construetor:
getModifiers() int
getParameterTypes() Class[]
newInstance(Object... initargs)

反射可以破坏封装
Field,Method,Constructor 这三类的对象都可以调用 .setAccessible(true); [/color]
------------------------------------------------------------
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics