赞
踩
0. 自述
自从大学毕业后开始做java开发有几年了,但是都是用现在比较流行的一些框架蒙头写业务代码,总有一种自己水平不行的感觉故而决定重新开始 在将java基础视频(待我看完后在分享视频网盘链接)简单过一遍后,然后在去重新学习其他东西,坚持每天学一点东西,也坚持在学完后开始写写博客来做一些记录,有点乱 后续有空就会一直修改 直到自己看着满意为止。
1. 局部变量与成员变量的区别与使用
简单区别:使用变量一般必须先声明、在赋值、然后才能使用;但局部变量没有默认值必须先声明 在赋值 在使用。
使用原则: Java中使用变量 遵循 “就近原则” 局部有就直接用局部的、局部没有就去本类的成员变量找、成员没有在去本类的父类中找。
2. String 类的相关方法及简单记法
string = “”;这是一个字符为空的字符串 可以调用String类的相关方法。
string = null; 这是一个空变量 调用String类的相关方法会报空指针错误。
其实下面这些也不用刻意去记 我只是看别人总结了下就复制过来了,平时开发写的多了也就自然而然记住了。
功能 | |||||
---|---|---|---|---|---|
判断 | 首 | 尾 | 中 | 空 | 判断 |
startsWith() | endsWith() | contains() | isEmpty() | equals()&&equalsIgnoreCase() | |
获取 | 截 | 长 | 取位 | 取元素 | |
substring() | length() | indexOf()&&lastIndexOf() | charAt() | ||
转换 | 大 | 小 | 拼串 | 转数组 | |
toUpperCase() | toLowerCase() | concat() | toCharArray()&&getBytes() | ||
其他 | 除空 | 切 | 换 | 字典排 | |
trim() | split() | replace() | compareTo() |
3. 封装、继承、多态
封装 隐藏对象的属性和实现细节,仅对外提供一个公共的访问方式。
好处:提高代码安全性和复用性
缺点:代码量增加(从另外一个角度,需要新建对外访问的方式)
子类没有找父类 父类没有找父类的父类 一直到找到结果。
子类、派生类
父类、基类、超类。
java中只能单继承,不能多继承,由于会出现指向不明。
开发原则:高内聚、低耦合。
优点:提高代码的复用性,让类与类之间产生关系 式多态的前提
弊端:类与类间产生关系,提高了耦合性。
1、子类只能继承父类的非私有成员变量。
2、子类不能继承父类的构造方法、但是可以通过super(参数)进行使用。
3、不要为了部分功能去使用继承。
4、当它们之间满足 is a 的关系时,可以考虑使用继承。 student is a person .
Map<String,String> map = new HashMap<String,String>();
父接口指向子类对象。map 是一个接口类 多态表现形式2
- 多态前提条件
1、要有继承(或者实现)关系。
2、要有父类引用(或父接口引用)指向子类对象。
3、要有方法重写(不然多态就没有什么意义)。
多态成员访问特点:
成员变量:编译看左边,运行看左边。
Animal an = new Cat();
an.age 编译期间会看左边有没有这个成员变量(Animal类中有没有age变量。)
成员方法:
非静态方法:编译看左边,运行看右边。//原因:方法有重写。
an.sleep(); Cat重写Animal的非静态方法sleep(),编译期间会看Animal类中是否有sleep方法 没有则编译报错,但是运行时会调用Cat类中的sleep方法。
静态方法:编译看左边,运行看左边。
多态中,只有访问非静态方法是编译 运行看右边 其他都是编译和运行都看左边,原因是方法有重写。
多态的好处
1、提高代码的扩展性。
2、提高代码的可维护性。
开发原则2 对修改关闭,对扩展开发。
多态弊端
父类(父接口)引用不能直接使用子类的特有成员。问题解决 可以通过向下转型实现 强制转换。
* HashMap*
HashMap(双列集合、无序(存和取的顺序不一致,不是里面内容排序不一致)集合、键具有唯一性值可以重复)
1、用于存储个数不固定的元素的容器,集合只能存储引用类型的数据。
HashMap<String,Integer> //正确
HashMap<String,int> //错误 int 为基本类型。
2、集合初始化
HashMap<Integer,String> map;
map = new HashMap<>(); //正确 这是jdk1.7的新特性:菱形泛型。
map = new HashMap<Integer,String>();//正确 推荐使用前两种写法。
map = new HashMap();//也正确,但不推荐。
3、泛型和包装类
泛型泛指某种特定的数据类型。
泛型只能是引用类型。
泛型一般只和集合相结合使用,主要用来明确集合中要存放的类型。
好处:提高代码的安全性。
HashMap map = new HashMap();
map.put("string","test");
map.put(1,2);
//上面写法是可以 但是不能明确集合存的类型。
Set<String> keys = map.keySet();//获取HashMap中所有key的单列集合
//增强for循环
for(String key : map.keySet()){}
* 包装类*
//包装类其实就是基本类型对应的应用类型(包装类)
//基本类型 引用类型(包装类)
byte Byte
short Short
char Character
int Integer
long Long
float Float
double Double
boolean Boolean
* 随意记*
JDK1.5的新特性:自动拆装箱
自动装箱:把基本类型的数据,转成其对应的引用类型。
自动拆箱:把引用类型的数据,转成其对应的基本类型。
Integer i = new Integer(10); JDK1.5前需要这样
Integer i = 10; 自动装箱。
int a = i; 自动拆箱。
集合只能存放引用类型,数组可以存引用类型也可以存基本类型。
ArrayList (单列集合、有序(存取顺序是一致,不是里面内容排序有序)可重复) 其他部分特性可参考集合HashMap。
asList();
数组转集合之后,不能进行增加或者删除操作 但是可以进行修改。
如果是基本类型的数组转集合,那么是把这个数组当做集合的一个对象来转的。
内存划分:
1、栈 存储局部变量 、所有代码的执行都是在栈中的。
2、堆 存储所有new出来的东西
3、方法区
4、本地方法区 和系统相关
5、寄存器 给CPU使用的。
使用变量遵循 就近原则 如果方法中有局部变量就用 没有就去找类的成员变量 在没有就是父类找。
子类默认构造方法有一个super(),且必须放在第一行。,用于子类对象访问父类数据前,对父类数据进行初始化。
由于所有的类都直接或者间接的继承自Object,Object类是所有类的父类,它里面只有一个空参构造方法,所以子类构造中默认访问的是父类的空参构造方法。
方法重新
@Override 方法重写注释。
1、父类的私有方法子类不能重写。
2、方法重写时,子类方法的访问权限不能低于父类方法的访问权限。
3、静态方法只能被静态方法重写(覆盖),这只是表现形式是被重写 其实重写只能是非静态方法。
总结:子类只能继承父类的非私有成员变量,不能重写父类的私有方法以及final修饰的方法但是final修饰的方法子类能用,重写非私有方法访问权限不能低于父类的访问权限,静态方法只能被静态方法重写(表现形式为重写其实覆盖,重写其实只能重写非静态方法。)。
用abstract修饰的类,里面可以定义抽象方法
1、有抽象方法的类一定是抽象类,或者接口、抽象类中不一定有抽象方法。
2、抽象类不能实例化、可以通过创建其子类对象来完成初始化(多态)。
3、抽象类不能实例化,但是有构造方法的,用于子类对象访问父类数据前 对父类数据进行初始化。
4、抽象类的子类 如果不是抽象类 则必须要重写父类的所有抽象方法。
不能和abstract共存的关键字:private final static
static: 静态方法可以被类名点的形式调用,但是抽象方法是没有方法体的,这样就没有意义了。
private:设计冲突 表示私有的 被它修饰的方法不能被子类重写,但是抽象方法要求子类必须重写 有冲突。
final:设计冲突 被它修饰的方法不能被子类重写,但是抽象方法要求子类必须重写 有冲突。
抽象方法:没有方法体的方法,用关键字:abstract修饰 public abstract void eat();
1、比抽象类更加抽象,里面没有构造方法。
2、接口的子类要么也是抽象类这样可以不用重写抽象方法,否则必须重写接口中的所有抽象方法。
接口成员变量
JDK1.7及以前
1、接口中的成员有且只能有 抽象方法或者常量。方法默认public abstract ;public static final;
JDK1.8
1、接口中可以定义有方法体的方法了
2、如果是静态可以直接写,如果非静态方法必须加上default。public default void show(){…}
类与类单继承 类与接口可以多实现 接口与接口之间可以多继承。
问题 如果不同接口中存在相同抽象方法 那么类实现这两个接口的调用问题????
1、成员特点区别。
抽象类中的成员比普通类多一种抽象方法(而且抽象方法可以不写)。
接口中有且只能有抽象方法(JDK1.8有带方法体的方法)
2、设计理念区别
抽象类:定义的是整个继承体系的共性内容。
接口:定义的是整个继承体系的扩展内容。
帮助理解上面两句话:猫狗都会吃饭、睡觉 他们有姓名和年龄。
部分的猫吃了神奇过,会飞了
class 部分猫 extends 猫类 implements Flying{}
for 循环加2
for(int i =0; i<=100; i+=2){}
增强for jdk1.5的新特性
外循环控制行数 内循环控制列数
break; 整个循环结束
continue;当前次循环结束 而且当前次循环中在continue后面的代码都不执行。
冒泡排序 相邻元素两两比较。
工具类两大特点: 一般把构造方法私有法private lei(){} 其他方法静态 这样就不去new 工具类了
正则表达式 pattern 看api
异常常说的异常。
编译期异常 非RuntimeException 异常 javac.exe test.java –> test.class.
必须处理 才能运行
运行时异常 RuntimeException 执行.class 字节码文件。
不处理但可以通过编译 执行时报错
try{
//尝试执行的代码
system.out.println(1/0);
system.out.println(“出现异常这句话是不会执行,直接到catch”);
}catch(){
//出现异常后的处理代码
System.exit(0);//有这句代码时 finally里面代码都不会执行。
return;
}finally{
一般是用来释放资源,正常情况下,里面代码永远会执行
system.out.println(“仍然会执行”);
system.out.println(“仍然会执行”);
}
system.out.println(“仍然会执行”);//与throws区别
system.out.println(“添加return语句是不会执行的”);
try catch finally 出现异常后 模块后面的代码仍然会执行
throws 出现异常后 异常代码后面的代码不会继续执行。
File 类提供三种构建方法。为了满足用户灵活多变需求。
File方法 创建删除
createNewFile(); //创建文件,如果文件不存在就创建返回true 存在则不创建返回false
File file1 = new File(“a.txt”);
boolean flag = file1.createNewFile();
mkdir(); //创建文件(单级)如果文件不存在就创建返回true 存在则不创建返回false
File file2 = new File(“aa”);
boolean flag = file1.mkdir();
mkdirs();//创建文件(多级)
File file3 = new File(“aa\bb\cc”);
boolean flag = file1.mkdirs();
delete();//删除文件(夹) java
File file4 = new File(“aa\bb\cc”);
boolean flag = file1.delete(); java中删除不走回收站 删除的问价夹必须是空文件夹
File 获取功能
getName(); //获取文件(夹)名字
getAbsolutePath(); //获取绝对路径的字符串形式。
getAbsoluteFile(); //获取绝对路径的File对象形式。
getPath(); //创建File对象的时候,用的是什么路径就返回什么路径 一般是用来获取相对路径
getParent(); 获取文件(夹)的父目录的字符串形式。拿绝对路径的
getParentFile();获取文件(夹)的父目录的File形式。
length();只能统计文件的大小。单位是字节
File 判断功能
exists();
isFile();文件
isDirectory();文件夹
列出
list(); 返回String[] //获取指定目录下所有的文件(夹)的名称数组
listFiles(); 返回File[] 获取指定目录下所有的文件(夹)的对象数组
分类
按流向分:
输入流 读取数据
输出流 写数据
按操作分:
字节流
InputStream 如:FileInputStream
OutputStream如:FileOutputStream
字符流
Reader
Writer
计算机最基本的存储单位是字节
在GBK码表中 一个中文占两个字节 在UTF-8中 一个中文占3个字节,数字,字母,特殊字符 不管什么码表都占1个字节。两种码表底层都包含了Ascii码表(描述字符和int类型间的关系) a:97 A:65 0:48 。。。
Eclipse的默认编码用的是GBK
IO流的顶层都是抽象类,稽核的顶层都是接口。
IO流的核心代码
1.创建输入流对象,封装数据文件
2.创建输出流对象,封装目的文件
3.定义一个变量,用来记录读取到的字节
4.循环读取,只要条件满足就一直都,并景读取到的内容记录给变量。
5.将读取到的内容写入到目的文件中
6.关闭流,释放资源。
字节流 可以操作任意类型的文件,但是操作中文内容时候 有可能出现乱码 就是文件不同码表一次读取可能不是完整一个中文可能为半个
常用语 图片 音频 视频等。
字符流 专门操作中文文件。
当一个文件能用微软的记事本打开,并且里面的内容正常 则可以考虑使用字符流。
递归 递归要有出口 次数不要太多 容易栈内存溢出 构造方法不能递归。
System.in 标准输入流 默认执行键盘
System.out 标准输出流 默认执行控制台
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
转换流
InputStreamReader OutputStreamWriter
FileInputStream in;
new InputStreamReader(in);
指定码表读写文件
new InputStreamReader(in,“utf-8”);
new OutputStreamReader(out,“gbk”);
utf-8 gbk 大小写都库 如uTf-8 Gbk等
InputStreamReader:字节流通向字符流的桥梁
OutputStreamReader:字符流通向字节流的桥梁。
utf-8 FileInputStream InputStreamReader java程序 OutputStreamReader FileOutputStream gbk
BufferedReader 高效字符输入流:可以一次读取一行数据。
BufferedWriter 高效字符输出流:可以一次写一行数据。
拷贝文件:
1.普通字节流一次读写一个字节 :FileInputStream FileOutputStream
*2.普通字节流一次读写一个字节数组
3.高效的字节流一次读写一个字节
4.高效字节流一次读写一个字节数据组
字节流没有一次读一行的。
5.普通字符流一次读写一个字符 FileReader FileWriter
*6.普通字符流一次读写一个字符数组
7.高效字符流一次读写一个字符 BufferedReader BufferedWriter
8.高效字符流一次读写一个字符数组
*9.高效字符流一次读写一行
BufferedReader readLine()
BufferedWriter write(String line)
BufferedWriter newLine();根据当前操作系统给出对应的换行符。
JDK1.6及其以前IO流的标准异常处理代码
FileInputStream fis = null;
FileOutputStreanm fos = null;
try{
fis = new FileInputStream(“C:\a.txt”);
fos = new FileOutputStream(“b.txt”);
}catch(Exception e){
e.printStactTrace();
}finally{
//以下主要是以防finally中的代码出现异常 而没有达到关流
try{
if(fis!=null){
fis.close();
}
}catch(IOException e){
e.printStackTrace();
}finally{
try{
if(fos!=null){
fos.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
JDK1.7及其以后IO流的标准异常处理代码 主要为释放资源 不用去自己写
try(
//写在try()中的内容,会在大括号{}中的代码执行完毕后,自动释放。
//原因是因为实现了AutoCloseable接口 FileInputStream FileOutputStream 都实现这个接口重写了接口中close()方法,才会自动释放资源
FileInputStream fis = new FileInputStream(“C:\a.txt”);
FileOutputStream fos = new FileOutputStream(“b.txt”);
){
读写处理逻辑 不用关流 自动关JDK1.7及其以后。
}
commocs-IO第三方jar包。
一个进程可以多条线程 线程恭喜当前进程的数据。
多线程并行: 多个线程同时执行 前提:需要多核CPU
多线程并发: 多个线程同时请求执行,但是一个CPU分时间片执行 但同时只能执行一个,于是就安排这些线程交替执行,由于时间短 看起来像同时执行的 其实不是。开多了程序会有阻塞感。
同一线程不能重复开启,否则回报 线程状态非法异常。
多线程的两种实现方式的区别
方式一。继承Thread
弊端:扩张性比较差,类继承了Thread不能再继承其他类了。
方式二:实现Runnable接口
扩展性比较强 可以实现接口的时候继承类。
Thread 成员方法getName()获取线程名字( 默认 命名规则:Thread-编号,编号从0开始)
多线程的安全(同步)问题
概述:多线程并发 操作同一数据,就有可能引发安全问题,此时就需要用到同步解决。
同步:
同步代码块:
格式:
synchronized(锁对象MyThread.class){
//要加锁的代码
}
//锁对象可以是任意类型的对象。
//不然使用同一把锁,不然可能锁不住。
同步方法:
非静态同步方法:
锁对象:this
静态同步方法:
锁对象:Mythread(类名).class
线程安全(同步),效率低
匿名对象
Cat cat = new Cat(); //这是一个叫cat的对象
new Cat();//这是Cat类的一个匿名对象,也可以叫Animal类的子类(Cat)的一个匿名对象
匿名内部类:
格式:new 类名(接口名){
//重写类中(接口中)的所有抽象方法。
}
本质:其实就是类(接口)的子类的匿名对象。
专业说法 :匿名内部类的本质其实是一个继承了类(或实现接口)的匿名的子类对象。
new Animal(){
public void eat(){…}
}.eat(); 与new Cat().eat();类似。
JDK 1.7 匿名内部类访问其所在的方法的局部变量时,该变量必须加final修饰,原因是为了延长该变量的声明周期。
JDK 1.8 取消了会自动加上final修饰。
public class Test{
public static void main(String[] arges){
final Demo demo = new Demo();//JDK1.7 //Demo demo 对象存放在栈里 也是main的一个局部变量 main方法执行完后会释放资源。栈里面会立即回收。
//Demo demo 在栈里 用完立即回收, new Demo();在堆里也是由Gc回收
new Thread(){
void run(){
demo.method(); //由于Demo是final修饰
使用final修饰符不仅会保持对象的引用不会改变,
而且编译器还会持续维护这个对象在回调方法中的生命周期.
所以这才是final变量和final参数的根本意义.
}
}.start(); //匿名内部类 存放在堆中 是由java GC回收 不定时回收。
}
}
网络模型
OSI(open system interconnection) 开放式系统互联
七层:应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
Tcp/IP
四层 应用层 传输层 国际互联层 网络接入层(主机-网络层)
网络编程三大特性
IP地址:设备在网络中的唯一标识 网关号码+主机地址
192.168.0.1
A类IP:第一段(192)是网关号码 后三段(168.0.1)主机地址
B类IP:前两段192.168是网关号码 后两段0.1主机地址
C类IP:前三段192.168.0式网关换 第四段1是主机地址
InetAddress Sting类型ip 和 IP地址对象互相转换。
端口号:每个程序在设备上的唯一标识。范围0-65536 0-1042基本系统已经用了或作为保留端口了。
协议:TCP UDP
UDP:面向无连接(朋友不在线 也可以给他的qq也能发消息) 只发送不管接受 每个包大小不超过64kb 不安全 不区分客户端和服务端 效率高
TCP:面向有连接 采用IO流 数据无大小限制 安全 效率低 区分客户端和服务端。
网络编程 socket编程 套接字编程
通信两端都独有自己的Socket对象 数据在两个Soceket之间通过IO流传输
我给你打电话 其实是咱之间相互说的话 通过两个手机在交互。
套接字:网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
客户端
1.创建客户端Socket对象,指定IP地址和端口号
2.通过Socket对象获取传输的IO流对象。
3.关闭流对象 //关了4 其实关了3
4.关闭Socket对象
服务端
1.创建服务端Socket(ServerSocket)对象,指定端口号
2.通过ServerSocket的accept()监听客户端连接,如果客户端有请求 数据验证后将返回一个Socket对象 和该客户端交互。
3.通过返回的Socket对象获取客户端的IO对象
4.关闭流
5.关闭Scoket 这个Socket是与客户端交互的Socket 也就是上面返回的socket 不是ServerSocket
java 平台版本划分
J2SE:标准版 可用于研发桌面应用程序
J2ME: 小型版 主要用于研发嵌入设备 被Android取代了
J2EE: 企业版 主要用于写平台(服务器端)代码
以上为JDK1.5之前
JDK1.5 后 正式更名为JavaSE,JavaME,JavaEE
java 之父 詹姆斯.高斯林
java语言特点 开源 、 跨平台。
源代码–> 编译(javae.exe)–>中间代码(字节码也就是.class)–>JVM识别。
JVM 保证代码跨平台 但其本身并不能跨平台。
JVM java虚拟机,用来报账Java程序跨平台的
JRE java运行环境,包括运行Java程序所需要的核心类库 和JVM
JDK Java 开发工具包 包括常用的开发工具和JRE。
switch case 最后一个break可以省略,其他break不可省略 否则可能会发生case穿透现象。
switch主要用于判断固定值。 if主要用于判断范围
switch(num) num类型:
JDK1.5以前 int,char,short,byte
JDK1.5以后:枚举
JDK1.7以后:String
方法重载:
同一类中 、 出现方法名相同、参数列表不同(个数不同或类型不同)两个方法及两个以上时 称为方法重载 与返回值类型无关。
方法重写
子父类间存在一模一样的方法时,包含返回值类型一样(或返回类型存在子父类关系)。
public 修饰的类成为顶级类 一个文件中只能有一个public修饰的类 且类名必须与文件名相同。
代码块: 就是用{}括起来的代码
分类
静态代码块:类一加载就执行,而且只执行一次 一般用于加载驱动DriverManager 在类的成员位置格式 static{}
构造代码块:里面定义的是所有构造方法的共性内容,因为它是优先于构造方法执行的。在类的成员位置格式{}
局部代码块:让变量尽可能早的从内存中释放掉,从而节约资源,提高效率。在方法局部位置格式{}
同步代码块: 用于解决多线程安全问题的。
成员变量:堆中(new 出的结果) 生命周期随着对象的创建而存在,对象的消失而消失
局部变量:栈中 生命周期随着方法的调用而存在, 随着方法的执行结束而消失。
StringBuilder 字符串缓冲区类 值可以改变 String 值不可以变。
泛型值针对引用类型。
单列集合 顶层接口:Collection
List接口:ArrayList(底层数据结构是数组) Vector已淘汰(底层数据结构是数组) LinkedList(底层数据结构是链表)
Set接口:HashSet(底层数据结构是哈希算法) TreeSet(底层数据结构是二叉树)
双列集合 顶级接口:Map
HashMap(底层数据结构是哈希算法)
TreeMap (底层数据结构是二叉树)
单列集合遍历方式 增加for内部实现基于迭代器 迭代器遍历 转数组遍历
1.通过稽核对象获取对应的迭代器对象
2.通过迭代器的hasNext方法判断有没有下一个元素
3.有就获取下一个元素 next()
Iterator it = has.iterator();
while(it.hasNext()){
String next = it.next();
}
List体系独有的遍历方式
1.普通for
2.列表迭代器:可以解决并发修改异常。
ListIterator <String> lit = has.listIterator();
while(lit.hasNext()){
String next = lit.next();
}
并发修改异常:
当遍历集合的同时,又往集合中添加(或者删除)元素,就有可能报并发修改异常。
解决方法
1.用列表迭代器解决。listIterator 调用列表迭代器自己的添加删除操作。
2.用CopyOnWriteArrayList 内部自己处理了并发修改异常
并发修改异常:ConcurrentModificationException
Collections 工具类 用于操作单列集合
sort() 排序(默认是升序)
reverse();反转
shuffle();随机置换(一般棋牌游戏的洗牌动作可以用到)
max();求最大
min();求最小
Properties集合类
它是一个双列集合,键值都是String,它是唯一一个可以和IO流直接结婚使用的集合类
它可以直接从流中读取数据,也可以直接写入数据到流中。
Properties p;
p.load(文件输入流);读取
p.store(文件输出流);写入
内存输出流 把整个内存当做一个缓冲区,可以往里面写数据,然后可以一次性的从内存中获取到所有数据
ByteArrayOutputStream
线程的生命周期
新建
就绪
运行(可能会发生阻塞(分阻塞(同步,IO阻塞)和等待(sleep/join/wait)))
死亡
关键字
this 本类当前对象的引用
static 可修饰 成员变量和成员方法,也可以形成静态块
static只能用于修饰内部类,用static修饰的内部类可以被类中的静态方法调用。final修饰符说明该类不允许被继承。
static修饰的方法,不直接能访问本类中的非静态(static)成员(包括方法和属性),本类的非静态方法可以访问本类的静态成员
(包括方法和属性)静态方法要慎重使用(原因是静态变量会一直存在,占用资源),且在静态方法中不能出现this关键字。
父类中是静态方法,子类中不能覆盖为非静态方法;在符合覆盖规则的前提下,在父子类中,父类中的静态方法可以被子类中的静态
方法覆盖,但无多态。(在使用对象调用静态方法时,实则是调用编译时类型的静态方法)
父子类中,静态方法只能被静态方法覆盖,父子类中,非静态方法只能被非静态方法覆盖。
java中的main方法必须写成static的,因为在类加载时无法创建对象,静态方法可以不通过对象调用所以在类的main方法。
所在在类加载时就可以通过main方法入口来运行程序。
final 可以修饰类、方法、变量 被修饰的变量其实是一个常量 只能赋值一次。
1、修饰的类 不能被继承,但是可以继承别的类。
2、修饰的方法:不能被子类重写(子类能用,但不能重写)。
3、修饰的变量:如果基本类型变量则值不能发生改变,类似常量。如果修饰引用类型,地址不能发生改变,但属性值可以发生变化。
final Zi zi = new Zi(“test”);
Zi zi = new Zi(“test11”); //错误
zi.setName(“ss”); //可以进行修改值。
修饰后不可 在new Zi对象了。
1.变量被final修饰,就会变成常量(常量应大写),一旦赋值不能改变(可以在初始化时直接赋值,也可以在构造方法里也可以赋值,
只能在这两种方法里二选一,必须为常量赋值)
final的常量不会有默认初始值
2.final修饰方法,被final修饰的方法将不能被其子类覆盖,保持方法的稳定不能被覆盖。
3.final修饰类,被final修饰的类将不能被继承。final类中的方法也都是final的。
在String类中,以字面值创建时,会到Java方法空间的串池空间中去查找,如果有就返
回串池中字符串的地址,并把这个地址付给对象变量。如果没有则会在串池里创建一个字符串对象,并返回其地址付购对象变量,
当另一个以字面时,创建对象时则会重复上述过程。如果是new在堆空间中创建String类的对象,则不会有上述的过程。
String类中的intern()方法会将在堆空间中创建的String类对象中的字符串和串池中的比对,如果有相同的串就返回这个串的串池中
的地址。不变模式在对于对象进行修改,添加操作是相当麻烦的,它会产生很多的中间垃圾对象。创建和销毁的资源的开销是
相当大的。这就是推荐大量使用StringBuffer,而不建议使用String的原因!
abstract
abstract关键字可以修饰类或方法。
abstract类可以扩展(增加子类),但不能直接实例化。
abstract方法不在声明它的类中实现,但必须在某个子类中重写。
采用abstract方法的类本来就是抽象类,并且必须声明为abstract。
abstract类不能实例化。
仅当abstract类的子类实现其超类的所有abstract方法时,才能实例化abstract类的子类。这种类称为具体类,以区别于abstract类。
如果abstract类的子类没有实现其超类的所有abstract方法,该子类也是abstract类。
abstract关键字不能应用于static、private或final方法,因为这些方法不能被重写,因此,不能在子类中实现。
final类的方法都不能是abstract,因为final类不能有子类。
不能放在一起的修饰符:final和abstract,private和abstract,static和abstract,因为abstract修饰的方法是必须在其子类中
实现(覆盖),才能以多态方式调用,以上修饰符在修饰方法时期子类都覆盖不了这个方法,final是不可以覆盖,private是不能
够继承到子类,所以也就不能覆盖,static是可以覆盖的,但是在调用时会调用编译时类型的方法,因为调用的是父类的方法,
而父类的方法又是抽象的方法,又不能够调用,所以上的修饰符不能放在一起。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。