首先考虑 对于这些问题 包含哪些类那些对象
应该具有哪些属性和方法
类和类之间具有哪种关系 关联 继承 聚集 组合 实现 多态
所有的paradigm都是对现实问题的抽象:
汇编是对机器语言的抽象
面向过程的语言是对汇编的抽象
对象更符合对于像是问题的抽象
对象都有对外服务的接口: 通过继承可以复用
对象隐藏内部服务的实现:通过聚合可以复用
resuable 可重用性
extensibility 可扩展性
维护和替换更加方便
组件 比对象更高层次的抽象 二进制级别:web service
定义成员变量可以初始化 如果不进行初始化 系统默认初始化 局部变量必须初始化
成员变量作用域为整个类体 0 false 应用类型默认为null
除基本类型外变量类型为引用类型,Java中对象是通过引用对其操作的。
如何在内存中区分类和对象?
类是静态的概念,在代码区。
对象是new出来的,位于堆内存,类的每个成员变量在不同的对象中都有不同的值,
除了静态变量,而方法只有一份,执行的时候才占用内存。
堆内存动态分配内存 对象只有在运行期间分配 因此new 新建对象 放在堆内存中
同一个类的每个对象有不同的成员变量存储空间
同一个类的每个对象共享该类方法
Java中进行函数调用中传递参数时 遵循值传递的原则:
基本类型传递的是该数据值本身,引用类型传递的是对对象的引用,而不是对象本身。
构造方法:
使用new + 构造方法创建一个新的对象
构造方法用来初始化对象的函数
构造方法与类同名且没有返回值 void 也不能写
当没有指定构造函数时 编译器自动添加 类名() { } 构造函数
指定了构造函数后 不再提供默认构造函数
命名规则:
类名首字母 大写
方法名 成员名 变量名 首字母小写
运用驼峰标识
方法的重载 一个类中定义相同名字 但参数不同的多个方法
调用时 会根据不同的参数表选择对应的方法
非静态方法是针对每个对象进行调用
this:
this关键字代表使用该方法的对象的引用
当必须指出当前使用方法的对象是谁时要使用this
有时使用this可以处理方法中成员变量和参数重名的情况
this可以看做是一个变量 它的值是当前对象的引用
static:
类中,static声明的成员变量为静态成员变量,它为该类的公用变量,
在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份。
用static声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,
所以在static方法中不可访问非static成员。
静态方法不再是针对某个对象调用,所以不能访问非静态成员。
可以通过对象引用或类名(不需要实例化)访问静态成员
包名规则:
Package 必须写在源代码第一行
公司域名倒过来
Java编译器把包对应于文件系统的目录管理,package语句中,
用‘.’指明包(目录)的层次。
编译后的class文件必须位于正确目录下 与包的层次完全的一致。:
该类的源码可能会产生影响 删除或转移至另外目录
使用其他类时必须写全包名 或者引入包 访问同意包下的类 不需要引入。
必须class文件的最上层包的的父目录必须位于classpath下
执行一个类需要写全包名
jar -cvf test.jar .
对于class的权限修饰 只可以用public和default
public类可以在任意地方被访问
default类只可以被同一个包内部的类访问
extends关键字实现类的继承:
通过继承,子类自动拥有了基类superclass 的所有成员-成员变量和方法
Java支持单继承 不支持多继承:一个子类只能有一个基类 一个基类可以派生出多个子类
private类权限
default包权限
protected 子类权限
public 公开
重写方法不能使用比被重写方法更严格的访问权限,相同方法名 参数列表和返回类型
重写时一定要copy函数头
super引用基类的成分。与this类似。
继承中的构造方法:
子类的构造过程中必须调用其基类的构造方法。(子类对象内部包含一个弗雷对象)
子类可以在自己的构造方法中使用super(argument_list)调用基类的构造方法。
使用this(argument_list)调用本类的另外构造方法
如果调用了super 必须写在子类构造方法的第一行。
如果子类的构造方法中没有显示地调用基类构造方法,则系统默认调用基类无参构造方法。
如果子类构造方法中既没有显示调用基类构造方法,而基类中又没有无参的构造方法,则编译出错,找不到符号。
Object类是所有Java类的根基类
类未使用extends关键字指明其基类,默认基类为object类。
toString() 类名@hashCode()
Object 的equals方法:x.equals(y) 当x和y为同一对象的引用时,返回true
String/Date 重写了Object的equals方法,
x.equals(y) 当x和y索引用到的对象 是同一类对象且属性内容相等时(并不一定是相同对象),
返回为true否则为false。 非空
对象转型:casting 父类-子类转型 父类引用指向子类对象 subclass d = (subclass)(new superClass())
一个基类的引用类型变量可以“指向”其子类的对象。
一个基类的引用不可以访问其子类对象新增加的成员(属性和方法)
可以使用 引用 变量instanceof 类名 来判断引用型变量所 指向 的对象是否属于该类或该类的子类。
子类对象可以当做基类对象使用称作向上转型(upcasting) 否则 向下转型 downcasting
动态绑定和多态:
动态绑定是指 在执行期间,非编译期间,判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
多态的存在有三个必要条件:继承、重写、父类引用指向子类对象
abstract 抽象类
abstract class abstract method
含有抽象方法的类必须声明为抽象类 抽象类必须被继承 抽象方法必须被重写
抽象类不能被实例化
抽象方法只需声明 不需实现
抽象类中可以包含非抽象方法
final:等同于const
final变量的值不能被改变:成员变量 局部变量
final方法不能被重写
final类不能被继承
接口:interface 抽象方法和常量值的定义的集合 一种特殊的抽象类
所有的方法都是抽象的 没有变量和方法的实现
只包含常量和方法的定义 都是静态变量和final变量
多个无关的类可以实现同一个接口
一个类可以实现多个无关的接口
接口与实现类之间存在多态性。
public static final int x;不属于特定的对象 不可更改的常量
接口内所有方法 不用添加abstract修饰符 全部是abstract
接口特性:
接口可以多重实现;
接口中声明的属性默认为 public static final ,也只能是public static final
接口中只能定义抽象方法,方法默认为public,也只能是public
接口可以继承其他接口,并添加新的属性和抽象方法。
异常 运行期错误
错误名字 行号
try { } catch(Exception e){e.printStackTrace();} finally {}
throws Exception {} 声明
throw new Exception(""); 定义所抛出的异常
try代码段包含可能产生例外的代码
try代码段后跟一个或多个catch代码段
每个catch代码段声明其能处理的一种特定类型的异常并提供处理的方法
当异常发生时,程序会中止当前的流程,根据获取异常的类型去执行相应的catch代码段。
finally段代码无论是否发生异常都会执行。异常处理统一的出口:
进行资源的清楚工作:关闭打开的文件 删除临时文件等
printStackTrace(); getMessage();
Java的异常处理机制使得异常事件 沿着被调用的顺序往前寻找
只要找到符合该异常的处理程序即可。
throwable Error(系统错误 虚拟机错误) Exception(一般需要用户显示声明或捕获):RuntimeException
自定义异常:
继承java.lang.Exception 类声明自己的异常类
在方法适当的位置 生成自定义异常的实例 并用throw语句抛出
在方法的声明部分用throws语句声明该方法可能抛出的异常
重写方法需要抛出与原方法所抛出异常类型一致异常或不抛出异常。
先逮小的 再逮大的
格式 考虑周全 异常
数组是引用类型
元素为引用数据类型的数组中的每一个元素都需要实例化
动态初始化:数组定义与为数组元素分配空间和赋值的操作分开进行
静态初始化:定义数组同时 为数组元素分配空间和赋值
*****常见算法*****
java.lang.String 不可变的字符序列
string-length 字符长度不是字节长度
StringBuffer 可变的字符序列 改变直接在其内存所在区域执行
StringBuffer和String类似,但StringBuffer可以对其字符串进行改变
StringBuffer()
StringBufer(String str)
java.io.File 类代表系统文件名-路径和文件名
Enum枚举类型
只能够取特定值中的一个;
使用enum关键字
java.lang.Enum
容器
java.util
Collection-Set(HashSet) List(ArrayList/LinkedList)
Map-HashMap
Set 没有顺序不可以重复
List 有顺序可以重复
Map 键值对 key-value
容器类对象调用remove contains等方法时 需要比较对象是否相等,
需要重写equals和hashCode(map)方法,实现自定义的对象相等规则。
相等的对象应该具有相等的hashCode
hashCode适合做索引
所有实现了Collection接口的容器类 都有一个iterator方法用以返回一个
实现了Iterator接口的对象。
Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
Iterator对象的remove方法 是在迭代过程中删除元素的唯一安全方法
不能使用容器的reomve(obj)方法 因为Iterator在进行遍历时,执行了锁定,
对当前元素进行锁定,不允许其他对象进行访问和修改。
增强For循环:for(Object o : c)
无法方便访问数组的下标值
无法针对集合的元素进行删除:内部也是调用Iterator
建议: 除了简单遍历并读出其中内容 不建议使用增强for循环
Set接口:
Collection子接口,Set接口没有提供额外的方法,
但实现Set接口的容器类中的元素是没有顺序的 且不可重复
HashSet TreeSet 与数学中集合对应
相同元素不会被重复添加
Comparable接口 compareTo
Array 读快改慢 改指的是针对整个list的更改
Linked 读慢改快
Hash之间
Map接口 存储 键值对
Map接口实现类 HashMap TreeMap
Map类中存储的键值对 通过键值标识 所以键值不能重复(equals->hashCode)
auto-boxing unboxing 自动打包 解包
自动将基础类型转换为对象
自动将对象转换为基础类型
Generic 泛型
jdk1.4以前类型不明确:装入集合类型都被当做Object对待 失去自己的实际类型
从集合中取出时 需要转型 效率低 容易产生错误
在定义集合时同时定义集合中对象的类型
增强程序的可读性和稳定性
优先使用泛型
一个图:
一个类:Collections
三个知识点:For增强For Generic泛型(极其重要) Auto-boxing/unboxing
六个接口:collection Set List Map Iterator(游标) Comparable(可应用泛型)
IO
Java程序中对于数据的输入 输出操作以流(stream)的形式进行,jdk提供了
各种各样的流类 用以获取不同种类的数据 程序中通过标准的方法输入或输出数据
输入流 输出流 站在程序的角度
字节流 字符流
节点流 处理流
字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer
节点流:从一个特定数据源 节点 读写数据 如文件 内存
处理流: 连接 在已存在的流 (节点流或处理流) 之上
通过对数据的处理为程序提供更为强大的读写功能
FileReader FileInputStream
FileWriter FileOutputStream
BufferedReader FileReader
BufferedWriter FileWriter
转换流
字节流转换为字符流
InputStreamReader OutputStreamWriter 字节数据到字符数据之间的转换
InputStreamReader 与 InputStream 套接
OutputStreamWriter 与 OutputStream 套接
转换流 在构造时可以指定编码集合
数据流
DataInputStream DataOutputStream 处理流,
分别套接在InputStream OutputStream上
提供了存取与机器无关的Java原始类型数据
PrintIO:
PrintWriter字符 PrintStream字节
Object流
直接将Object写入或读出
transient关键字
serializable接口
externalizable接口
Thread:
一个程序中不同的执行路径
进程 静态概念 class文件 EXE文件
进程执行指的是 进程中的主线程开始执行
实际运行的都是线程。
一个CPU只能支持单线程
Java的线程是通过 java.lang.Thread 实现的
VM启动时会有一个由主方法所定义的线程
创建Thread实例来创建新的线程
每个线程都是通过某个特定Thread对象所对应的run()完成其操作,方法run()成为线程体
通过调用Thread的start()启动线程
线程启动必须调用Thread类的start()方法 通知cpu 给予时间执行任务
线程和进程区别:
每个进程都有独立的代码和数据空间(进程上下文) 进程间的切换会有较大开销
线程可以看做是轻量级的进程,同一类线程共享代码和数据空间
每个线程有独立的运行栈和程序计数器(PC) 线程切换的开销小
多进程:在操作系统中能同时运行多个程序 任务
多线程:同一应用程序中有多个顺序流同时执行
线程的创建和启动:
第一种:
定义线程类实现Runnable接口
Runnable 只有一个方法: public void run() 定义线程运行体
使用Runnable接口可以为多线程提供共享的数据
在实现Runnable接口的类的run方法定义中可以使用Thread的静态方法:
public static Thread currentThread();
第二种:
定义一个Thread子类并重写其run方法
class MyThread extends Thread {
public void run(){ }
}
能使用接口不要从Thread继承!!!
线程状态转换
isAlive();
getPriority();
setPriority();
Thread.sleep();
join();
yield();
Wait();
notify();
notifyAll();
线程优先级 默认为5 1-10
同一线程类可以启动多个线程
线程同步:
public synchronized void methodName(){} 执行方法的过程中锁定当前对象
Java对象互斥锁 保证了共享数据操作的完整性,每个对象都对应一个称为 “互斥锁”的标记
这个标记保证在任一时刻 只能有一个线程访问该对象
关键字synchronized 修饰某个对象某一方法时 表明 执行该方法的过程中锁定当前对象的这段方法
即在任一时刻 只能由一个线程访问
Object.wait()
this.wait() 当前对象wait--
-访问当前对象的线程 拿到该方法所属对象的锁 遇到阻塞 此时使用wait()
锁定对象 锁定线程后 才有资格调用wait
wait时 锁不再属于当前对象 Object类方法 其它进程可以访问该锁的对象
sleep 锁仍然属于当前对象 Thread类方法
this.notify(); 叫醒一个正在wait该对象的线程
this.notifyAll() 叫醒等待该对象的其他所有线程
network
tcp ip 详解
ip Internet protocol 无连接数据包传送 数据包路由选择和差错控制
tcp 字节流非报文流 面向连接的协议 不可靠的因特网上提供可靠的 端到端的字节流通信协议
tcp 类似打电话 三次握手
udp user data protocol 发送封装的原始IP数据报 发送时无需建立连接 不可靠连接
(网络电话 聊天 视频等)可以丢报
socket
两个Java应用程序 通过一个双向的网络通信连接实现数据交换 双向链路一端称为Socket
Socket 实现 client-server 连接
Java.net 包定义两个类(TCP) Socket 和 ServerSocket 分别用来实现双向连接的client和server端
建立连接所需的寻址信息为远程计算机的IP地址和端口号(Port number) 2个字节 65536个端口号
一个应用程序最多跑65536个网络应用程序
1024以下的端口号 系统占用
TCP端口 65536个
UDP端口 65536个
先启动Server 再执行client
Socket包-berklin
berklinDB-现代数据库的根源
Server
ServerSocket ss(port #)
while(true){//一直监听
Soceket s = ss.accept() //等待连接
OutputStream
InputStream
s.close() //客户端连接断开
}
Client
Socket s = (host - "ip", port #) //--Attempt to connect
OutputStream //客户端写入 服务器端读取
InputStream // 服务器端回复 客户端读取
s.close()
DatagramSocket
DatagramPacket
byte[]
ByteArrayOutputStream
DataOutputStream
ds.send(dp);
ds.receive(dp);
awt Abstract Window Toolkit
GUI Graphics User Interface
Container Component 是 AWT 两个核心类
Component:
Container {Button/TextArea/Label/TestFields/List}
Window Panel
Frame Dialog Applet
Component 对象不能独立显示 必须存放在某一Container对象中
Container是Component的子类
Panel对象可以拥有自己的布局管理器 FlowLayout
布局管理器
管理Component在Container中的布局 不必直接设置Component的大小和位置
每个Container都有一个布局管理器对象,当容器需要对某个组件进行定位或判断
其大小尺寸时 调用其布局管理器 调用Container的SetLayout方法改变其布局管理器对象
LayoutManager:
FlowLayout Panel类 默认布局管理器 默认对齐方式居中 水平
BorderLayout Frame 东西南北中
GridLayout
CardLayout
GridBagLayout
事件监听:
事件源对象-----当某种事件发生--向监听器传送某种事件对象---接到事件对象后进行某种处理--
实现了某种监听器的接口的类的对象========注册=======事件源对象
ActionListener 接口
Monitor implements ActionListener
actionPerformed(ActionEvent e){}
Monitor m = new Monitor();
Button b1.addActionListener(m);
e.getSource() 返回的对象实际为Button
实现了observer 观察者模式
TextField事件监听
public void actionPerformed(ActionEvent e){
TextField tf = (TextField)e.getSource();
持有对方引用---门面模式(对外) 调停者模式(对内) 大管家
class MyMonitor implements ActionListener {
TFFrame tf = null;
public MyMonitor(TFFrame tf) {
this.tf = tf;
}
public void actionPerformed(ActionEvent e){}
class TFFrame extends Frame {
TextField num1,num2,num3;
public void launchFrame() {
Button btnEqual = new Button("=");
btnEqual.addActionListener(new MyMonitor(this));
}
inner class可以直接访问包装类内的属性和方法 拥有外部包装类的引用
该类不允许或不需要其他类进行访问时
注意内部类的位置与成员变量 及成员方法一个级别
paint方法 paint(Graphics g) 被自动调用
Frame需要被重画时 显示或重新显示 改变窗口大小时
不需要被显示调用
鼠标事件适配器
MouseAdapter 实现了 MouseListener接口
可使用其子类作为MouseEvent的监听器
使用适配器可以避免监听器类定义没有必要的空方法
repaint() - update() - paint() ---双缓冲
windows事件
windowAdapter 匿名类-方法内部类
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setVisible(false);
System.exit(0);
}
}
)
反射机制
reflection
程序运行过程
xxx.class ----ClassLoader 将其Load到内存中CodeSegment----
----code segment main ----运行环境找到main方法开始执行----
运行过程中会有更多的class被load到 内存 动态加载机制
ClassLoader的类加载机制:
并非一次加载,需要的时候再加载(运行期动态加载)
static语句块在加载后执行一次
dynamic语句块每次new新的对象都会执行:
等同于构造方法中的语句,用的较少
-verbose:class 可以详细查看程序加载过程
动态语句块
class D {
{
System.out.println("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
}
}
new 一个对象时 会被重新调用
JDK内置ClassLoader
bootstrap ClassLoader(最早启动) implemented by native language(C 汇编等)/ load the core classes of jdk
System.out.println(String.class.getClassLoader()); null 最核心的类的加载 这些加载器名称为null
首先Load ClassLoader 其他的ClassLoader再Load其他的Class
extesion ClassLoader 扩展类 loader class from jre/lib/ext
application ClassLoader load user-define classes ClassLoader.getSystemClassLoader()
other ClassLoader SecureClassLoader URLClassLoader
JDK Class Loader 的层次关系 (不是继承)
bootstrap ClassLoader 对象
extesion ClassLoader 对象 对象 包含一个parent引用指向 bootstrap ClassLoader 对象
application ClassLoader 对象 包含一个parent引用指向 extesion ClassLoader 对象
other ClassLoader 对象 包含一个parent引用指向 application ClassLoader 对象
Class Loader在load的时候首先找到上一层loader 是不是load过了 如果已经load了 不再load
自己写的String.class 永远没有机会执行(破坏性的代码)
java.lang.Class
反射机制 创建对象
Class c = Class.forName("T");
Object o = c.newInstance();
Method[] methods = c.getMethods();
for(Method m : methods) {
System.out.println(m.getName());
if(m.getName().equals("mm")) {
m.invoke(o);
}
}
if(m.getName().equals("m1")) {
m.invoke(o,1);
for(Class paramType : m.getParameterTypes()) {
System.out.println(paramType.getName());
}
//m.getParameterTypes();
}
if(m.getName().equals("getS")) {
Class returnType = m.getReturnType();
System.out.println(returnType.getName());
}