面向对象多态性
运行时行为,将父类的引用指向子类 person p1 = new man()
在编译期,只能调用父类种申明的方法(那如何调用子类的方法呢?【向下转型 Man man = (Man)p1】),在运行期,执行的是子类重写的方法,在多态情况下,父类中的方法称为虚拟方法。
instance of 关键字
判断是否是类的实例,防止向下转型时出现异常。 p1 instance of A
finalize()对象回收前会调用该方法
equals 与 == 的区别
equals :比较对象,适用于引用数据类型,Object中定义的equals方法与==作用相同,在不同类中进行重写,用于比较两个类的具体内容是否相同。
== :运算符 对于基本数据类型比较数值大小,对于引用数据类型,比较地址值
包装类 基本数据类型
int Integer
char character
Integer中保存了从-128到127的整数
Integer m=1;
int n=1;
System.out.println(m=n) //true
Integer m=128;
int n=128;
System.out.println(m=n) //false
//相互转换
Integer i = 10;
String str1 = i + "";
String str2 = String.valueOf(i);
String str = "123";
Integer i1 = Integer.parseInt(str);
static 关键字
类中用static关键字修饰的属性和方法,可直接通过类调用,随着类的加载而加载。
单例设计模式
懒汉式
class Lhs
{
private Lhs(){};
private static Lhs lhs = null;
public static Lhs getlhs()
{
if(lhs==null){
synchornized(Lhs.class){
if(lsh==null) lhs = new Lhs();
}
}
return lhs;
}
}
饿汉式
class Ehs
{
private Ehs(){};
private static Ehs ehs = new Ehs();
public static Ehs getehs()
{
return ehs;
}
}
代码块
静态代码块 static{} 随着类的加载而加载
非静态代码块 {} 随着对象的创建而执行
final 关键字
final 修饰的方法 不能被重写
final 修饰的类 不能被继承
抽象类与抽象方法
用abstract关键字修饰
由abstract修饰的类,不能实例化,有构造器,方便子类继承
由abstract修饰的方法,没有方法体,由子类重写 public abstract void a();
接口
interface 定义
JDK7之前:只能定义全局常量(public static final a;)和抽象方法(public abstract void a();)
JDK8之后:还可以定义静态方法(static)和默认方法(default)
一个类只能继承一个父类,但可以实现(implements)多个接口
抽象类与接口
相同点:都不能实例化
不同点:抽象类可继承,有构造器,单继承。接口可实现,没有构造器,多实现。
多线程
4中创建线程的方法
1.继承Thread类,重写run方法
class MyThread extends Thread{
public void run(){}
}
MyThread myThread = new MyThread();
myThread.start();
2.实现runnable接口
public MyThread implements Runnable{
public void run(){}
}
MyThread myThread = new MyThread();
Thread t = new Thread(myThread);
t.start();
3.实现callable接口
class MyThread implements Callable{
public object call throws Exception(){
return xx;
}
}
MyThread mt = new MyThread();
FutureTask ft = new FutureTask(mt);
Thread t= new Thread(ft);
t.start();
try{
Object obj = ft.get();
}
4. 线程池
3种解决线程安全问题的方法
1.同步代码块 synchornized(锁/同步监视器){同步代码}
任何一个类都可以充当锁,多线程要共用同一把锁
2.同步方法 public synchornized void show(){}
非静态同步方法 锁为this
静态同步方法,锁为当前类本身
3.lock锁(手动)
ReentrantLock lock = new ReentrantLock()
try{
lock.lock();
//同步代码
}catch(Exception e){
}finally{
lock.unlock();
}
wait和sleep
相同点:都能让线程进入阻塞状态
不同点:sleep:Thread类中,任何场景下调用,不会释放锁。
wait:Object类中,synchornized中使用,会释放锁。
Java集合
分为Collection(单例数据)和map(双例数据)接口
Collection
List:有序,可重复集合
ArrayList,底层Object[]实现,线程不安全,效率高
LinkedList,底层双向链表实现
Vector,底层Object[]实现, 线程安全,效率低
Set:无序,不可重复集合 HashSet,TreeSet,LinkedHashSet,在Set中存放对象,一定要重写equals和hashcode方法。
HsahMap底层实现原理
JDK7之前:数组+链表,JDK8之后:数组+链表+红黑树
实例化后,底层创建长度为16的一维数组,map.put(k,v),调用k所在类的hashcode,计算哈希值,哈希值再经过某个算法(%16)得到在一维数组中的位置,若为空,添加成功,若不为空,与已存在数的哈希值进行比较,若不同,添加成功,若相同,调用k所在类的equals方法,若返回false,添加成功,若返回true,用v替换之前的v。
IO流
按数据单位分为字节流和字符流
按流的流向分为输入流和输出流
按流的角色分为节点流和处理流
抽象基类 | 节点流 | 缓冲流(处理流) |
InputStream | FileInputStream | BufferedInputStream |
OutputStream | FileOutputStream | BufferedOutputStream |
Reader | FileReader | BufferedReader |
Writer | FileWriter | BufferedWriter |
对象序列化要求:1 实现接口Serializble,2 当前类提供一个全局常量(public static final long SerialVersionUID = 34234334L),3 内部所有属性必须可序列化
网络编程
客户端
InetAddress inet = InetAddress.getByName("127.0.0.1");
Socket socket = new Socket(inet,8992);//端口号
OutputStream os = socket.getOutputStream();
os.write("xxx".getbytes());
os.close();
socket.close();
服务端
ServerSocket ss = new ServerSocket(8992);
Socket socket = ss.accept();
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[5];
baos.read(buffer);
反射
动态语言的关键
通过反射,可以调用类的私有结构
反射的动态性
public Object getobject(String classPath){
Class c = Class.forName(classPath);
return c.newInstance();
}
调用运行时类的属性和方法
Class c = Person.class;
Object obj = c.newInstance();
Person p = (Person)obj;
Field name = c.getDeclaredField("name");
name.setAccessible(true);
name.get(p);
name.set(p,"Tom");
Method show = c.getDeclaredmethod("show");
show.setAccessible(true);
show.invoke(p,"CHN");//对象,形参
Object returnValue = show.invoke(p,"CHN");