java se基础

JAVA笔记
一、环境搭建
开始安装
1)安装准备
Eclipse(开发工具)、jdk(Java Development Kit) JAVA开发工具包
2)安装JDK (Java Development Kit) 是 Java 语言的软件开发工具包(SDK)。
打开jdk,安装到c盘下,打开我的电脑属性,添加环境变量
变量名:Path
路径:C:\Program Files (x86)\Java\jdk1.6.0_10\bin
3)安装开发工具
开发工具有Myeclipse,eclipse两个工具,建议使用eclipse ,傻瓜式安装;
4)测试环境
在window打开命令窗口win+r 输入cmd进入dos命令窗口 输入java 打印一串java信息代表环境搭建成功。
在inux下 打开命令窗口Ctrl+Alt+t 输入java 打印一串java信息代表环境搭建成功。



二、Eclipse  window 常用快捷键
1.Eclipse快捷键
1)Ctrl+1 快速修复
2)Ctrl+D: 删除当前行
3)Alt+/ 代码助手完成一些代码的插入 ,自动显示提示信息
4)Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)
5)Alt+↑ 当前行和上面一行交互位置(同上)
6)Alt+← 前一个编辑的页面
7)Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)
8)Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性
9)MyEclipse 快捷键4(ALT+CTRL)
10)Alt+CTRL+↓ 复制当前行到下一行(复制增加)
11)Alt+CTRL+↑ 复制当前行到上一行(复制增加)Ctrl+/ 注释当前行,再按则取消注释
12)Ctrl+D删除当前行。
13)Ctrl+Q跳到最后一次的编辑处
14)Ctrl+M切换窗口的大小
15)Ctrl+I格式化激活的元素Format Active Elements。
16)Ctrl+F6切换到下一个Editor
17)Ctrl+F7切换到下一个Perspective
18)Ctrl+F8切换到下一个View

2.window快捷键和常用命令
以下命令全部在dos窗口中生效
1)Services.msc     打开服务
2)Shutdown –s –t   定时关机
3)Shutdown –a     取消定时关机
4)Calc 计算器
5)Mspaint 画画
6)Notepad 记事本
7)Regedit 注册表
8)Gpedit.msc 本地策略
9)Msconfig 系统配置


三、语法基础
1.代码注释
1)单行注释
//代码     快捷键   Ctral +/
2)多行注释
/* 代码*/ 快捷键   Ctral +shift+/

3)文档注释
/**
*   代码
**/
快捷键  alt+shift+j

2.数据类型
1)基本数据类型
i.Byte
ii.Short
iii.Int
iv.Long
v.Double
vi.Float
vii.Boolean
viii.char

2)引用数据类型
1.类
2.接口
3.数组
         注:详细参考后面内容
3.运算符
1)算术运算
包含:+  -  *  /  %

2)关系运算
包含: >, >=,<,<= ,!=,表达式1?表达式:表达式3

3)逻辑运算
包含:!, && ,||, &,|

4.流程控制
1)顺序结构
自顶而下,逐步细化
2)选择结构
条件判断是依指定变量或表达式的结果,决定后续运行的程序,最常用的是if-else、switch指令
3)循环结构
循环是指一段在程序中只出现一次,但可能会连续运行多次的代码。

5.数组
1)定义
数据类型[] 变量名=new 数据类型[数组长度];

2)实例
定义并初始化的三种方式
int[] ints=new int[3];
Ints[0]=1;
Ints[1]=2;
Ints[2]=3;
Int[] ints=new int[]{1,2,3}
Int[] ints={1,2,3};

3)数组的复制
System.arraycopy(数组1,0,数组2,数组, 数组1.length);

6.BREAK CONNECTION的法
Break: 一般用于循环、switch,可以跳出一层循环,在switch中用跳出switch;
Connection:只用于循环,结束本次循环,不结束本层循环
Break 跳出多层循环
Flag:
     For(int i=0;i<10;i++)
{
For(int j=0;i<10;j++)
{
Break flag;
}
}
7.循环
循环的三种方式
While  
Do while 不管怎样循环体都会执行一次
For

8.IF
      IF
      用法:当条件为真时,执行代码块1,反之 执行代码块2;
     If(条件表达式)
{
   代码块1;
}Else{
   代码块2;
}
9.递归
    递归就是自己调用自己,一般用于执行相同的代码块,method必须有一个出口。
四、类与对象
1.类
类 是方法和属性的集合
类的特点:封装、继承、多态
2.对象
类 对象=new 类();
注意:构造方法初始化参数不超过5个,当超过时使用Getters、Setters赋值;
3.抽象类
Abstract class 类名 
4.接口
1)接口一般定义的是常量和一些抽象方法。抽象类中可以包含抽象方法,也可以 有非抽象方法,但是有抽象方法的类一定是抽象类。抽象方法不能有方法体。
2)在引用接口时,接口的引用指向实现的对象,尽量定义为接口或父类的引用。 这其中有可能用到多态的知识。引用接口用implements。
3)接口(interface)只能定义抽象方法而且默认为是Public。常量是public static final 修饰的
4)通过implements来引用接口。例:Class runnrtmp inplements runner.
5)多个无关类可以实现一个接口,!!!!接口的引用指向实现的对象。
6)一个类可以实现多个无关的接口(这点和继承要有所区别)
7)和继承一样,接口与实现类之间存在多态性。
8)接口可以继承其他的接口,并添加新的属性和抽象方法。
9)在类中实现接口的方法时必须加上public修饰符
5.内部类
类里面内嵌入多个类
分类:静态内部类、匿名内部类
1)静态内部类
内部类可以由private、protected、public、缺省修饰
静态内部类可以访问外部类里面的静态属性和静态方法
2)匿名内部类
new classname{
成员变量和方法;
}

注意:匿名内部内访问外面的变量要用Final修饰




6.封装、继承、多态
继承
子类 extends 父类
与继承有关的修饰符:abstract static final
继承的好处
   减少代码冗余
   使维护变得简单
     更容易扩展
      重写方法(overload)重载(override)与方法重写的区别
相同点
方法的名称相同
都可以用于抽象方法和抽象方法之同
  不同点
方法重写要求参数签名必须相同、而方法重载签名不允许相同
    方法重写必须要求返回类型相同,方法重载不做限制
注:在基础上派生出放映特殊事务的类(java只支持单继承),变量不能被继承,属性不能被重写



多态
继承的表现就是多态,一个对象多种形态 多态是建立在继承关系之上 
类型转换需要发生继承关系
向上转型:
父类 对象1=new 子类();
对象1.方法或属性
对象1 参照父类中的结构
向下转型
子类 对象2 =(子类)new 父类();
对象2.方法或属性
注意:转换前必须发生多态

Instanceof

对象1 instanceof 类名

判断一个对象1是否是类的实例


封装
由private关键字修饰的属性和方法;
7.扩展
修饰符
类的修饰符:默认、public(公有的),private(私有的),,protected(受保护的)
属性修饰符:public protected private default
方法修饰符:
可见性修饰符:synchronized volatile
序列化修饰符:transient  native
Static修饰符
               静态方法或静态属性
     static 修饰的属性或方法可以使用类名点出来
   作用域全局
    static{}程序代码块 在初始化时执行一次且只会执行一次
final 修饰符
常量 全局常量和类常量
修饰的变量不能被更改
Final 引用数据类型
       内容可以被修改 但引用不能变

权限修饰符的可访问权限级别
位置 Public Protected Default Private
同一类 √ √ √ √
同一包中不同类 √ √ √ x
不同包中的子类 √ √ x x
不同包中的非子类 √ X x X

面向对象的关键字
Public、protected、default、private、This、Super、Instanceof、extends、
Implments、Final、Static
Java存储区域
1.栈  存储变量(堆得引用)
2.堆  类的属性/数组的值
1)全局方法区 :
a)普通方法区
b)静态方法区
2)全局数据区 :
没有对战的引用关系(就是不用new 实例),全是存储静态static属性



五、集合框架
  定义:集合框架就是为了表示和操作集合而规定的一种统一的标准体系结构。
   集合框架包含的三大内容:接口、接口的实现、接口的运算。
1. 接口:即表示集合的抽象类型。
2. 实现:接口的具体实现。
3. 算法:实现某个集合框架中的接口的对象上完成某种有用的方法。
接口:Collection List Set Map Iterator
1)Collections
位于集合框架的顶层,一个Collections代表一组Object,即Collection的元素(Elements)。
2)List
分为:ArrayList<T>   LinkedList
i.ArrayList
它是一个增强型的数组
List list=new List();
ArrayList<T> lists=new ArrayList<T>
常用方法:
Add():添加一个元素
Size():返回元素的数量
get(int index):返回指定位置的元素
Remove(int index):移除指定位置的元素
iteracor():返回一个迭代器
ii.LinkedList
它是List接口的另一个重要实现类。它的底层是用双向循环来实现的,所以便于将新元素插入指定位置。它的效率低,但是增删效率很 高。适用于增删比较频繁。
实例化:
LinkedList linkedlist=new LinkedList();
LinkedList linkedlist=new LinkedList(Collection c);
常用方法:
  Add():添加一个元素到最后
  Size():返回元素的数量
  Removelast():移除最后一个元素

3)Set
集合框架 支持Set接口两种普通的实现:HashSet  TreeSet 实现SortedSet接口。
分为:HashSet和TreeSet

i.HashSet
散列表
Set set=new HashSet<E>();
方法:
HashSet()        构建一个空的哈希集
HashSet(Collection c)        构建一个哈希集 并添加集合所有元素
HashSet(int  size)  构建一个拥有具体容量的空哈希集

ii.TreeSet
作用:当要从集合中以有序的方式插入和抽取元素
Set set=new TreeSet<E>();


4)Map
A.HashMap
HashMap是Map的实现类
创建一个HashMap对象实例
  HashMap hash=new HashMap();
常用方法:
  Get(Object  key)    获得与关键相关的值
  Put(Object key,Object value) 添加key 对应相应的值
  Remove(Object key)   移出key 对应相应的值
HashMap和Hashtable区别
  推出:hashtable 是jdk1.0 是提出的(属于保留类)
  性能:hashmap采用异步处理方式,性能较高,hashtable相反
  线程安全:hashmap非线程安全,hashtable属于线程安全
  Null:hashmap允许null作为其key或value:hashtable则不允许


B.treeMap
Treemap 一般用于排序
5)Iterator
用于对集合容器遍历,通常称作迭代器。
6)Conllections
Conllections:为集合全框架实现的一个便捷的操作工具类。
1) 可以让非线程安全的接口变成线程安全:
   List list = Collections.synchronizedList(List<T> list) ;
   Set set = Collections.synchronizedSet(Set<T> s) ;
   Map map = Collections.synchronizedMap(Map<K,V> m) ;

集合总结:打开


六、基础类
常用类:Object 、String 、StringBuffer 、 Date、 Calendar、 Math、 Random
1.Runtime
关机:Runtime.getRuntime().exec("shutdown -s -t 100");

2.System
System.in   获取键盘输入流
System.in.read() 获取键盘输入code
System.currentTimeMillis();
获取当前系统时间

3.Object
所有对象原始类
Java.lang.object 在lang包下
常用方法
  toString();
返回该对象的字符串表示。
  eauals();
指示其他某个对象是否与此对象“相等”。
Object obj1,obj2;
obj1==obj2  //判断内存地址
obj1.equal(obj2)//默认判断内存地址 当内存地址不相等时 比较内容
String str1,str2
Str1==str2//判断内在地址
Str1.equals(str2)//判断内容

4.String
i.初始化
1.String str=”hello”;
2.String str=new String(“Hello”);
ii.区别:不用new 初始化一个对象 new 初始化两个对象
iii.常用方法
Lenth
返回此字符串的长度。
getBytes()
使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
indexOf()
返回指定字符在此字符串中第一次出现处的索引。
indexOf(int ch, int fromIndex)
返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜
isEmpty()
当且仅当 length() 为 0 时返回 true
matches(String regex)
告知此字符串是否匹配给定的正则表达式。
replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
Contains( )
` 当且仅当此字符串包含指定的 char 值序列时,返回 true。





5.StringBuffer
主要处理可变的字符串
   StringBuffer sb=new StringBuffer(“asdfasdf”)
  常用方法
方法名 说明
Append() 追加字符串
reverse() 反转字符串的方法
Insert 在指定位置插入字符串
Delete(int start,int end) 删除调用对象中从start ---end 位置的字符串
Replace(int start,int end,String str); 使用一组字符替换另一数组。将用替换 字符串从start 到end 位置结束

6.Date
表示特定的瞬间,精确到毫秒。
Date date=new Date();
Date.toString();
常用方法
Before()
   判断当前日期是否在指定日期之前
   After()
   判断当前日期是否在指定日期之后

7.Calendar
类是一个抽象类
Calendar cal=Calendar.getInstance();
获取年月日时分秒
cal.get(Calendar.YEAR)

cal.get((Calendar.MONTH)+1)

cal.get(Calendar.DATE)

cal.get(Calendar.HOUR)

cal.get(Calendar.MINUTE)

cal.get(Calendar.SECOND)

cal.get(Calendar.AM)

8.Math
用于执行基本数学运算的方法
Math.方法和属性
详细参考API



七、异常处理(Exception)
1.什么是异常
异常是程序在执行时发生的事件,它会打断指令的正常流程,编译时不会报错,运行时会出错。
2.异常处理机制
Try{
     //正常代码;
}Catche(异常类型 异常对象){
//异常处理代码;
}
Finally{
//不管如何都要执行的语句
}
特殊
Try{
}
Catch{
}
3.异常的分类
1)Checked异常
  Java中凡是继承自Exception,而不继承自RuntimeException类的异常都是非运行时异常。

2)Runtime异常
RuntimeException类是Exception类的子类,它叫做运行时异常,Java中的所有运行时异常都会直接或者间接地继承自RuntimeException类。

4.Try catch 嵌套

5.使用多重catch
6.Finaly使用
不管怎样Finally中的代码都会执行
7.Throw throws
1)Throw
throw关键字通常用在方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即停止,它后面的语句都不执行。通过throw抛出异常后,如果想在上一级代码中来捕获并处理异常,则需要在抛出异常的方法中使用throws关键字在方法声明中指明要跑出的异常;如果要捕捉throw抛出的异常,则必须使用try—catch语句。
2)Throws
throws关键字通常被应用在声明方法时,用来指定可能抛出的异常。搜索多个异常可以使用逗号隔开。


8.自定义异常
写一个类继承Exception 重写 toString()、getMessage()方法
模板:
Class 异常类名  extends Exception{
代码块;
}

      
八、IO流
1.文件(File)
File能新建、删除、重命名文件和目录,File不能访问文件内容本身。如果需要访问文件内容本身,需要用到输入流/输入出流。

使用递归遍历文件目录
  参考代码笔记
删除指定盘符下的文件和文件夹
参考代码笔记
2.字符流
1)Writer
写文件:Writer字符输出流
public abstract class Writer extends Object implements Appendable,
Closeable, Flushable
1)Appendable能够被添加 char 序列和值的对象。
2)Closeable表示关闭的数据源或目标。
3)Flushable刷新该流的缓冲。
4)Writer是抽象类,文件操作,需要子类FileWriter参与实例。
Writer wirter = new FileWriter(File file);
5)一般与BufferedWriter完成高效写入。
2)Reader
Readable将字符读入指定的字符缓冲区。。
表示关闭的数据源或目标。
Reader是抽象类,文件操作,需要子类FileReader参与实例。
Reader reader = new FileReader(File file);
一般与BufferedReader完成高效读取。

3.字节流
1)OutputStream
写文件:OutputStream字节输出流
OutputStream是整个io包中字节输出流的最大父类,定义如下:
public abstract class OutputStream extends Object implements
Closeable, Flushable
Closeable表示可以关闭的数据源或目标。
Flushable刷新该流的缓冲,OutputStream的flush()方法无任何操作。
OutputStream是抽象类,文件操作,需要子类FileOutputStream参与实例。
OutputStream os = new FileOutputStream(File file);
OutputStream os = new FileOutputStream(File file, boolean append);

2)InputStream
读文件:InputStream字节输入流
InputStream是整个io包中字节输入流的最大父类,定义如下:
public abstract class InputStream extends Object implements Closeable
1)Closeable表示关闭的数据源或目标。
2)InputStream是抽象类,文件操作,需要子类FileInputStream参与实例。
InputStream is = new FileInputStream(File file) ;

4.二进制流
1)DataOutputStream
读文件:dataoutputStream 二进制输出流
InputStream是整个io包中字节输入流的最大父类,定义如下:
public class DataOutputStreamextends FilterOutputStreamimplements DataOutput
1)Closeable表示关闭的数据源或目标。
2)dataoutputStream是普通类,文件操作,
FileOutputStream参与实例。
  Fileoutputstream os=new Fileoutputstream(路径);
  DataOutputstream doos=new DataOutputstream(os);
2)DataInputStream
读文件:Datainputstream 二进制输入流
InputStream是整个io包中字节输入流的最大父类,定义如下:
public class DataInputStreamextends FilterInputStreamimplements DataInput
1)Closeable表示关闭的数据源或目标。
2)InputStream是普通类,文件操作,
FileInputStream参与实例。
InputStream is = new FileInputStream(File file) ;
  DataInputStream dis=new DataInputstream(is);
5.序列化对象(Serializable)
必须实现java.io.Serializable接口,不需要保存的属性使用ansient声明
ObjectOutputStream序列化对象,
ObjectInputStream反序列化对象
serialVersionUID
九、JDBC
1.数据库模式
DDL:数据库模式定义语言,关键字:create
DML:数据操纵语言,关键字:Insert、delete、update
DCL:数据库控制语言 ,关键字:grant、remove
DQL:数据库查询语言,关键字:select     

2.JDBC接口
Connection  对象代表与数据库的连接。
Statement 执行数据库操作的接口
PreparedStatement 预编译sql语句执行数据库操作的接口

Resultset 结果集,用于遍历查询到的数据
3.连接数据库
1)加载驱动
Class.forName(“com.mysql.jdbc.Driver”);
//将类加载到内存中
2)打开链接
Connection connection=DriverManager.getConnection(URL,USER,PWD);
3)操作数据
…………
4)关闭链接
Connection.close();
4.事务管理
1)事务的特性(acid)
tomic(原子性)
Consistency(一致性)
Isolation(隔离性)
Durability(持久性)

2)事务的使用
1.开启事务
Connection.setAutoComit(false);
2.提交事务
Connection.comit();

3.回滚事务
Connection.rollback();
5.批处理
1)Statement
Statement statement=Connection.createStatement();
Statement.addBatch(sql1);
Statement.addBatch(sql2);
Statement.executeBatch();
2)preparedStatement
preparedStatement pstmt=conn.preparedStatement(sql);
pstmt.setObject(1,values);
pstmt.addBatch();
pstmt.setObject(1,values);
pstmt.addBatch();
pstmt.executeBatch();

    

十、多线程
1.定义
  进程就是程序运行时的一个实例,线程可以看做单独地占有CPU的时间执行相应的代码。

2.线程程特点
1.多线程在运行时,系统自动在线程之间进行切换。
2.由于多个线程共存于同一块内存,线程之间的通信非常容易
3.Java将线程视为一个对象。线程要么是Thread类的对象,要么是接Runnable的对象
4.当多个线程并行运行时,具有较高优先的线程将获得较多的CPU时间片
5.优先级是0到10的整数,并且它公表示 线程之间的相对关系。
6.多个线程共享一组资源时,有可能在运行时产生冲突。必须采用synchronized关键字协调资源,实现线程的同步。

3.线程的常量和方法
常量:
Thream.MAX_PRIORITY  最大优先级 10
Thream.MIN_PRIORITY   最小优先级  1
Thream.NORM_PRIORITY 默认优先级  5
方法:
方法名 说明
currentThread()
Sleep(int n) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
Yield() 合当前运行的放弃执行,切换到其它线程
isAlive 判断线程是否处于执行的状态
Start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
Run() 该方法由start()方法自动调用
stop 使线程停止执行
Suspend() 使线程暂停执行,不退出可执行状态
Resume() 使暂停的线程继续执行
setName(String s) 改变线程名称,使之与参数 name 相同。
getPriority() 返回线程的优先级
setPriority(int p) 更改线程的优先级。
Join()  等待该线程终止。
4.

5.线程的使用
6.线程的生命周期
7.用过Runnable接口实现多线程
适合多个相同程序代码的线程去处理同一资源的情况,把虚拟CAP(线程)同程序的代码、数据有效分离,较好的体现面向对象的设计思想。

8.线程的同步
synchronized (this)
9.线程的通信
Wait 线程等待
Notify 线程换醒
Nofiyall 换醒所有等待中的线程
10. 死锁
11.扩展
十一、网络编程
1、TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,
     也就是说,在收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要
     经过三次对话(有人叫握手)才能建立起来:
     1)主机A对主机B:“我现在要发数据给你,可以吗”?
     2)主机B对主机A:“可以,你什么时候发”?
     3)主机A对主机B:“我现在就发”。
     主要用于HTTP、FTP、Telnet等对数据准确性有要求情况!


2、IP是电脑,端口是应用程序

3、Socket代表服务端,ServerSocket代码客户端

4、客户端的输入流就是服务端的输出流,反之一样。

5、UDP与TCP区别
  1)连接
       TCP连接,协议可靠、效率低;UDP无连接,协议不可靠,效率高。
  2)传输模式
       TCP流模式,UDP数据报模式。
  3)传输大小
       TCP在连接中可进行大数据传输,UDP的数据报大小限制在64k内。
   4)准确性
        TCP保证数据正确性,UDP可能丢包。

1.常用的类
1)InetAddress
2)URL
3)URLConnection
4)URLDecoder  (解码)
5)URLEncoder
2.TCP
3.UDP
十二、JAVA 高级特性
1. 静态导入
1) 导入类的静态属性
import static java.lang.System.out;
out.println("haha");
2) 导入类的静态方法
import static java.lang.Math.*; // 导入Math类的所有静态成员
int num = abs(-10);

2. 增强for循环
1) 作用: 对存储对象的容器进行迭代  
2)  jdk5以前怎么迭代
3) 增强for循环迭代数组
String [] arr = {"a", "b", "c"}; //数组的静态定义方式,只试用于数组首次定义的时候
// 传统方式
for(int i=0; i<arr.length; i++) {
// i依次表示数组的角标
String s = arr[i];
System.out.println(s);
}
System.out.println("-------------------------------------");
// 在jdk5中我们可以使用增强for循环迭代
// 增强for循环括号里写两个参数,第一个是声明一个变量,变量类型必须是数组元素的类型
// 第二个就是需要迭代的容器
// for循环会循环容器的length次, 每次都将容器的第n-1个元素赋值给声明的变量
for(String s : arr) {
// 循环体, 执行arr.length
// 每次都将arr中的第n-1个元素给s
System.out.println(s); //
}
3. 基本数据类型的包装类
int --> Integer
byte --> Byte
short --> Short
long --> Long
char --> Character
double --> Double
float --> Float
boolean --> Boolean

1) Integer x = 1; x = x + 1;  经历了什么过程? 装箱 拆箱  装箱
2) 为了优化,虚拟机为包装类提供了缓冲池, Integer池的大小 -128~127 一个字节的大小
3) String池
Java为了优化字符串操作 提供了一个缓冲池
面试题:
String s = “abc” 和 String s = new String(“abc”) 的区别
String s = new String(“abc”) 创建了几个对象
String s = “a” + “b” + “c” + “d” 创建了几个对象
String s1 = “a” String s2 = “b”  String s3 = s1 + s2;  s3==”ab”?

/*1. String s = "abc", 虚拟机首先会检查String池里有没有"abc"对象(通过equals方法)
// 如果有,直接返回引用,如果没有,会在池里创建一个“abc”对象,并返回引用
String s1 = "abc";
String s2 = "abc";
System.out.println(s1==s2); // result: true
*/

/* 2. String str = new String("abc");
不管缓冲池是否有"abc", 都会在堆内存创建一个"abc"对象,返回引用
// 此时,负责检查并维护缓冲池,其实堆内存的对象是缓冲池中"abc"对象的一个拷贝
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1==s2); // result: false
*/

/* 3. String s = "a" + "b" + "c" + "d";  java编译器有个合并已知量的优化功能
// 在编译阶段就把"a" + "b" + "c" + "d" 合并为 ”abcd“
String s = "a" + "b" + "c" + "d";
// String s = "abcd";
System.out.println(s=="abcd");// result: true
*/

/* 4.  String s1 = "a"; String s2 = "b"; String s3 = s1 + s2;
// String是常量,不能相加的,java如何实现的?
StringBuilder sb = new StringBuidler(s1);
sb.append(s2);
s3 = sb.toString();

也就是说实际上s3是方法返回的String对象
凡是方法返回的字符串对象都是在堆内存的
*/
String s1 = "a";
String s2 = "b";
String s3 = s1 + s2; // 堆内存的对象
System.out.println(s3=="ab");// result: false

4) 单列集合 Collection
List list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");

// 传统方式1
/* 1.获得迭代器
Iterator iter = list.iterator();
// 2.循环判断迭代器是否有下一个
while(iter.hasNext()) {
String str = (String) iter.next(); // 将迭代器的指针移向下一个,并将迭代当前指向的元素返回
System.out.println(str);
}
*/
// 传统方式2
for(Iterator iter=list.iterator(); iter.hasNext(); ) {
String s = (String) iter.next();
System.out.println(s);
}
System.out.println("--------------------------------");
// 增强for循环, 没有使用泛型的集合能不能使用增强for循环迭代?能
for(Object obj : list) {
String s =  (String) obj;
System.out.println(s);
}

5) 双列集合 Map
Map map = new HashMap();
map.put("a", "aaa");
map.put("b", "bbb");
map.put("c", "ccc");

// 传统方式迭代1
// 1. 获得所有的key
Set keys = map.keySet();
// 2.迭代keys获得所有的key
Iterator iter = keys.iterator();
while(iter.hasNext()) {
String key = (String) iter.next(); // a b c
// 3.根据key获得对应的value
String value = (String) map.get(key);
System.out.println(key + "=" + value);
}
System.out.println("---------------------------------");
// 传统方式2,必须掌握这种方式
// 1.获得所有的键值对Entry对象
Set entrys = map.entrySet();
// 2.迭代出所有的entry
iter = entrys.iterator();
while(iter.hasNext()) {
Map.Entry entry = (Entry) iter.next();
// 分别获得key和value
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println(key + "=" + value);
}
System.out.println("-------------------------------------");
System.out.println("增强for循环迭代,");
// 增强for循环迭代,
// 原则上map集合是无法使用增强for循环来迭代的,
// 因为增强for循环只能针对实现了Iterable接口的集合进行迭代
// Iterable是jdk5中新定义的接口,就一个方法iterator方法
// 只有实现了Iterable接口的类,才能保证一定有iterator方法
// java有这样的限定是因为增强for循环内部还是用迭代器实现的

// 而实际上,我们可以通过某种方式来使用增强for循环
for(Object obj : map.entrySet()) {
// obj 依次表示Entry
Map.Entry entry = (Entry) obj;
System.out.println(entry.getKey() + "=" + entry.getValue());
}
6)集合迭代注意问题
// 在使用迭代器迭代集合的过程中,不能对集合进行增删操作
@Test
public void test4() {
List list = new ArrayList();

list.add("wangwu");
list.add("zhangsan");
list.add("lisi");

Iterator iter = list.iterator();
while(iter.hasNext()) {
String name = (String) iter.next();
if("wangwu".equals(name)) {
// 从集合中删掉
//list.remove(name);
// 迭代过程中删除元素需要调用迭代器的方法
iter.remove(); // 删除我迭代的集合被我迭代的最后一个元素
}
}
// 1 2 4
System.out.println(list.size());
}

@Test
public void test5() {
List list = new ArrayList();

list.add("aa");
list.add("bb");

// 使用ListIterator迭代器
ListIterator listIterator = list.listIterator();
while(listIterator.hasNext()) {
listIterator.next();
// 迭代过程中增加元素
listIterator.add("cc");
}
System.out.println(list.size());
}
7) 增强for循环注意问题
//在使用增强for循环时,不能对元素进行赋值
int[] arr = {1,2,3};

for(int num : arr) {
num = 0;
}

System.out.println(arr[1]);

4. 可变参数
1) jdk5中方法的形参可以定义为可变参数,传入实参个数可变
// 设计一个方法求n个数的和
public static int getSum(int... arr) {
// 可变参数在方法中仍被看做一个数组
int sum = 0;
for(int num : arr)
sum += num;
return sum;
}

2)Arrays.asList为例演示传入不同参数的情况
// list长度为3
List list = Arrays.asList("a","b","c");
// list长度为1, 因为考虑1.4语法
String[] arr = {"a","b","c"};
List list = Arrays.asList(arr);
// 同时符合1.4和1.5的语法,此时会优先考虑1.4的语法
// 原因是有了新功能要保证以前的代码不出错,向后兼容
// 现在就需要将arr作为一个元素存入集合
Object obj = arr;
List list2 = Arrays.asList(obj); // 此时只符合1.5的语法,不符合1.4的语法,没有歧义

List list3 = Arrays.asList(new Object[]{arr}); // 优先考虑1.4,所以数组会拆开
//System.out.println(list3.size());
// 基本数据类型数组只符合1.5的语法
int[] nums = {1,2,3};
list = Arrays.asList(nums);
System.out.println(list.size());
5. 枚举
问题:对象的某个属性的值不能是任意的,必须为固定的一组取值其中的某一个
解决办法:
1)在setGrade方法中做判断,不符合格式要求就抛出异常
2)直接限定用户的选择,通过自定义类模拟枚举的方式来限定用户的输入
写一个Grade类,私有构造函数,对外提供5个静态的常量表示类的实例
3)jdk5中新定义了枚举类型,专门用于解决此类问题
4)枚举就是一个特殊的java类,可以定义属性、方法、构造函数、实现接口、继承类
//枚举类就是一个java类,也可以声明属性,方法,构造函数
public enum Grade4 {
A("90-100"),B("80-89"),C("70-79"),D("60-69"),E("0-59");
private String value;
private Grade4(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
//枚举类就是一个java类, 也可以继承抽象和实现接口
public enum Grade5 {
// 抽象类不能创建实例对象
A("90-100"){
// new了一个Grade5的子类实例
public String toLocaleString() {
return "优";
}
}
,B("80-89"){
// new了一个Grade5的子类实例
public String toLocaleString() {
return "良";
}
}
,C("70-79"){
// new了一个Grade5的子类实例
public String toLocaleString() {
return "中";
}
}
,D("60-69"){
// new了一个Grade5的子类实例
public String toLocaleString() {
return "差";
}
}
,E("0-59"){
// new了一个Grade5的子类实例
public String toLocaleString() {
return "不及格";
}
};

private String value;
private Grade5(String value) {
this.value = value;
}

public String getValue() {
return value;
}

// 对外提供一个方法,返回枚举的本地信息
// 一个方法不知道如何实现,可以定义为抽象的
public abstract String toLocaleString();

}

练习:请编写一个关于星期几的枚举WeekDay,要求:
•枚举值:Mon,Tue,Wed,Thu,Fri,Sat,Sun  星期一。。。。星期日
•该枚举要有一个方法,调用该方法返回中文格式的星期。


6. 反射
1)java代码的阶段:一段java代码在程序运行期间会经历三个阶段: source-->class-->runtime
2) Class 对象:  在java中用一个Class对象来表示一个java类的class阶段
Class对象封装了一个java类中定义的成员变量、成员方法、构造方法、类名、包名等
获得class对象的三种方式和区别:
// 1. 根据给定的类名来获得  用于类加载
String classname = "cn.itcast.reflect.Person"; // 来自配置文件
Class clazz = Class.forName(classname); // 此对象代表Person.class

// 2. 如果拿到了对象,不知道是什么类型   用于获得对象的类型
Object obj = new Person();
Class clazz1 = obj.getClass(); // 获得对象具体的类型

// 3. 如果是明确地获得某个类的Class对象  主要用于传参
Class clazz2 = Person.class;
// 在java中所有的类型都会对应一个Class对象 int Integer
Class intClazz = int.class;
Class intarrClazz = int[].class;
Class voidClazz = void.class;
3)反射
反射就是获得一个java类的各个组成部分
// 反射类的成员方法
Class clazz = Person.class;
Method method = clazz.getMethod(methodName, new Class[]{paramClazz1, paramClazz2});
method.invoke();

// 反射类的构造函数
Constructor con = clazz.getConstructor(new Class[]{paramClazz1, paramClazz2,...})
con.newInstance(params...)

// 反射类的属性
Field field = clazz.getField(fieldName);
field.setAccessible(true);
field.setObject(value);
4) 反射用在哪里
到底框架是什么?  框架就是将开发中大量重复的代码集中起来写个通用的程序
框架就是用反射来实现的, 框架需要现在的类调用将来写的类
框架是将来的程序员调用的,框架不能实现完整的功能,框架只是一些一些通用的代码;
框架要依赖将来写的类来运行.
现在写的类要调用将来写的类,我们先针对接口进行调用,将来的类需要实现接口,那么方法就固定了
但是将来写的类的类名我们无法获知,这时就需要调用者通过配置文件告诉框架具体的类名

7. 泛型
1) 泛型是一种可变化的类型, 类型不确定,需要调用者来指定

2) 用途:
一个类的多个成员方法用到的参数类型或返回值类型都是未知的类型,但又需要是同一个类型,就可将方法的
参数类型定义为泛型,此泛型必须在类上先予以声明才能在方法中使用
一个方法的多个参数和返回值需要是同一个类型,也可以用泛型来解决,在方法返回值前面声明泛型

泛型的细节:
1) 泛型到底代表什么类型取决于调用者传入的类型,如果没传,默认是Object类型
2) 使用带泛型的类创建对象时, 等式两边指定的泛型必须一致
原因: 编译器检查对象调用方法时只看变量,然而程序运行期间调用方法时就要考虑对象具体类型了
3) 等式两边可以在任意一边使用泛型 在另一边不使用 (考虑向后兼容)

3. 泛型的基本概念
以List<E>为例:<>念着typeof 例, List<String> 就是 List typeof String
List<E>中的E称为类型参数变量     方法定义参数形式参数 
List<Integer>中的Integer称为实际类型参数
整个List<E>称为泛型类型   GenericType
整个List<Integer>称为参数化的泛型类型

4. 泛型的使用
1)使用带泛型的类时,在创建对象时可以为泛型指定实际类型参数,指定的具体类型相当于给泛型传参
2)子类在继承父类的时候,可以为父类定义的泛型指定实际类型参数
class B<T>
class A extends B<String>
通过子类A获得的父类类型就是一个参数化的类型
3)调用方法时传入参数的具体类型将作为方法中泛型的实际类型
















猜你喜欢

转载自lishdfsdf.iteye.com/blog/2249932