面向对象
类的定义和对象的创建
//定义了一个类Liwl,保存该源码为文件Liwl.java。即类名与文件名一致
public class Liwl{
public static void main(String[] args){
System.out.println("hello,java");
}
}
类的属性和方法
public class Liwl {
public String name = "liwanliang";
public Integer age = 30;
public static void main(String[] args){
Liwl liwl01 = new Liwl();
//liwl01.name = "hello,world"
System.out.println(liwl01.age)
}
}
//通过liwl01.name = "hello,world"的语句,无法保证类的安全性,不太满足类的封装
类的封装
类的属性设置为私有
public class Liwl {
private String name;
private Integer age;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public Integer getAge(){
return age;
}
public void setAge(Integer age){
this.age = age;
}
}
/*
说明:this表示对象自己。在类定义中,类的方法访问类的属性和访问,通过this访问。
*/
构造方法
构造方法的定义和重载
public class Liwl {
private String name;
private Integer age;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public void setAge(Integer age){
this.age = age;
}
public Integer getAge(){
return age;
}
public Liwl(){
System.out.println("无参数构造函数");
}
public Liwl(String name,Integer age){
System.out.println("有参数的构造函数");
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Liwl liwl01 = new Liwl("liwanliang",30);
}
}
this关键字
static关键字
静态变量以及静态方法,一般通过类调用,而非对象
静态变量
public class Liwl {
public static void main(String[] args) {
LiwanLiang liwl001 = new LiwanLiang("liwanliang",30);
liwl001.WORK_PLACE = "哈哈";//静态变量是对象共享区域,通过对象修改静态变量
System.out.println(LiwanLiang.WORK_PLACE);
}
}
class LiwanLiang extends Liwl {
public static String WORK_PLACE;
private String name;
private Integer age;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public void setAge(Integer age){
this.age = age;
}
public Integer getAge(){
return age;
}
public LiwanLiang(){
System.out.println("无参数构造函数");
}
public LiwanLiang(String name,Integer age){
System.out.println("有参数的构造函数");
this.name = name;
this.age = age;
}
public void run(){
}
}
静态方法
public class Liwl {
public static void main(String[] args) {
LiwanLiang liwl001 = new LiwanLiang("liwanliang",30);
liwl001.WORK_PLACE = "哈哈";
System.out.println(LiwanLiang.WORK_PLACE);
LiwanLiang.run();
liwl001.run();
}
}
class LiwanLiang extends Liwl {
public static String WORK_PLACE;
private String name;
private Integer age;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public void setAge(Integer age){
this.age = age;
}
public Integer getAge(){
return age;
}
public LiwanLiang(){
System.out.println("无参数构造函数");
}
public LiwanLiang(String name,Integer age){
System.out.println("有参数的构造函数");
this.name = name;
this.age = age;
}
public static void run(){
System.out.println("我是静态方法");
}
}
静态代码块
当类被加载时,静态代码会被执行, 由于类只会被加载一次,因此静态代码块只会执行一次
public class Liwl {
public static void main(String[] args) {
LiwanLiang liwl001 = new LiwanLiang("liwanliang",30);
liwl001.WORK_PLACE = "哈哈";
System.out.println(LiwanLiang.WORK_PLACE);
LiwanLiang.run();
liwl001.run();
}
}
class LiwanLiang extends Liwl {
public static String WORK_PLACE;
private String name;
private Integer age;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public void setAge(Integer age){
this.age = age;
}
public Integer getAge(){
return age;
}
public LiwanLiang(){
System.out.println("无参数构造函数");
}
public LiwanLiang(String name,Integer age){
System.out.println("有参数的构造函数");
this.name = name;
this.age = age;
}
public static void run(){
System.out.println("我是静态方法");
}
static {
System.out.println("我是静态代码块");
}
}
类的继承
重写父类方法
public class Liwl {
public void sayHello() //重写了父类的sayHello方法
{
System.out.println("Hi");
}
public static void main(String[] args) {
Liwl liwl = new Liwl();
liwl.sayHello();
}
}
class LiwanLiang extends Liwl {
public static String WORK_PLACE;
private String name;
private Integer age;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public void setAge(Integer age){
this.age = age;
}
public Integer getAge(){
return age;
}
public LiwanLiang(){
System.out.println("无参数构造函数");
}
public LiwanLiang(String name,Integer age){
System.out.println("有参数的构造函数");
this.name = name;
this.age = age;
}
public void sayHello(){
System.out.println("hello");
}
public static void run(){
System.out.println("我是静态方法");
}
static {
System.out.println("我是静态代码块");
}
}
super关键字使用父类方法
public class Liwl extends LiwanLiang{
public Liwl(){
super("liwanliang007",30);
}
public void sayHello(){
super.sayHello(); //通过super关键字,直接使用父类的方法
}
public static void main(String[] args) {
Liwl liwl = new Liwl();
System.out.println(liwl.getName());
liwl.sayHello();
}
}
class LiwanLiang {
public static String WORK_PLACE;
private String name;
private Integer age;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public void setAge(Integer age){
this.age = age;
}
public Integer getAge(){
return age;
}
public LiwanLiang(){
System.out.println("无参数构造函数");
}
public LiwanLiang(String name,Integer age){
System.out.println("有参数的构造函数");
this.name = name;
this.age = age;
}
public void sayHello(){
System.out.println("hello,I am father class");
}
public static void run(){
System.out.println("我是静态方法");
}
static {
System.out.println("我是静态代码块");
}
}
final关键字拒绝重写父类方法
类的多态
java多态是通过父类类型的变量,引导子类类型的对象,根据子类对象特征的不同,得到不同的结果。
interface LiwanLiangWork{
String ADDRESS = "无锡";
String NEWADDRESS = "江苏";
void work();
}
class LiwanLiangWorkImpl01 implements LiwanLiangWork {
public void work() {
System.out.println("我的工作地点"+ADDRESS);
}
}
class LiwanLiangWorkImpl02 implements LiwanLiangWork {
public void work(){
System.out.println("我的新工作地点"+NEWADDRESS);
}
}
public class Liwl {
public static void main(String[] args) {
LiwanLiangWork liwl01 = new LiwanLiangWorkImpl01();
LiwanLiangWork liwl02 = new LiwanLiangWorkImpl02();
whereWork(liwl01);
whereWork(liwl02);
}
public static void whereWork(LiwanLiangWork w){
w.work();
}
}
多态中的类型转换
多态中,将子类的对象当作父类类型使用,此种情况叫做向上转型,向上转型不需要显示转换,但是此时不能通过父类变量调用子类中的特有方法。
以下代码【错误】:
public class Liwl {
public static void main(String[] args) {
LiwanLiangWork liwl01 = new LiwanLiangWorkImpl01();
LiwanLiangWork liwl02 = new LiwanLiangWorkImpl02();
whereWork(liwl01);
whereWork(liwl02);
}
public static void whereWork(LiwanLiangWork w){
LiwanLiangImpl01 l = (LiwanLiangImpl01) w; //这里对象的类型转换,使得该方法在传入LiwanLiangWork子类型对象时,调用另外子类的特定方法而报错
l.work();
}
}
匿名内部类
public class Liwl {
public static void main(String[] args) {
whereWork(new LiwanLiangWork(){
public void work(){
System.out.println("匿名工作地点");
}
});
}
public static void whereWork(LiwanLiangWork w){
w.work();
}
}
//以new Object(){}方式作为方法的参数,这就是匿名内部类
抽象类和接口
/*
抽象类:LiwanLiangHome
*/
abstract class LiwanLiangHome{
abstract void call();
public void sayBye(){
System.out.println("bye");
}
}
public class Liwl extends LiwanLiangHome {
public void call(){
System.out.println("liwanliang在叫");
}
public static void main(String[] args) {
Liwl liwl = new Liwl();
liwl.call();
liwl.sayBye();
}
}
interface LiwanLiangWork{
String ADDRESS = "无锡";
void work();
}
class LiwanLiangWorkImpl implements LiwanLiangWork {
public void work() {
System.out.println("我的工作地点"+ADDRESS);
}
}
public class Liwl extends LiwanLiangWorkImpl {
public static void main(String[] args) {
Liwl liwl = new Liwl();
liwl.work();
}
}
异常及异常类
在程序运行过程中,内存,磁盘,网络等发生异常导致的程序异常,比如内存溢出,内存不足,磁盘空间不足,读写失败,网络中断等
java提供的异常机制,来处理发生异常时,使程序针对性处理
错误表示系统内部错误或者资源耗尽等仅靠程序本身不能恢复执行的问题
异常表示程序本身能够正常处理的问题
try...catch...finally
throws
集合类
保存确定个数的元素使用数组,保存不确定个数的元素使用集合类(容器类)
- 集合类
- 单列集合 Collection
- 元素有序可重复 List
- ArrayList
- LinkedList
- Vector
- 元素无序不重复 Set
- HashSet
- LinkedHashSet
- TreeSet
- HashSet
- 元素有序可重复 List
- 双列集合 Map
- HashMap
- LinkedHashMap
- TreeMap
- HashTable
- Properties
- HashMap
- 单列集合 Collection
集合与泛型
对象从集合中取出时,编译类型变成Object类型,一般需要显示的强制类型转换
泛型限制传入范围,取出的对象也不用强制类型转换
Collection-List-ArrayList
public class Liwl {
public static void main(String[] args) {
ArrayList<String> liwl = new ArrayList<>();
liwl.add("liwl01");
liwl.add("liwl02");
System.out.println(liwl);
System.out.println(liwl.size());
System.out.println("第一个元素:"+liwl.get(0));
System.out.println("第二个元素:"+liwl.get(1));
}
}
Iterator接口遍历元素
import java.util.ArrayList;
import java.util.Iterator;
public class Liwl {
public static void main(String[] args) {
ArrayList<String> liwl = new ArrayList<>();//泛型的使用
liwl.add("liwl01");
liwl.add("liwl02");
System.out.println(liwl);
System.out.println(liwl.size());
System.out.println("第一个元素:"+liwl.get(0));
System.out.println("第二个元素:"+liwl.get(1));
Iterator<String> it = liwl.iterator();
while ( it.hasNext()) {
Object obj = it.next();//返回的是Object类型的对象
System.out.println(obj);
}
}
}
for...each循环
import java.util.ArrayList;
public class Liwl {
public static void main(String[] args) {
ArrayList<String> liwl = new ArrayList<>();
liwl.add("liwl01");
liwl.add("liwl02");
for ( Object obj: liwl) {
System.out.println(obj);
}
}
}
Collectioin-Set-HashSet
import java.util.HashSet;
import java.util.Iterator;
public class Liwl {
public static void main(String[] args) {
HashSet<String> liwl = new HashSet<>();
liwl.add("liwanliang");
liwl.add("liwl");
Iterator it = liwl.iterator();
while ( it.hasNext()) {
Object obj = it.next();
System.out.println(obj);
}
/*
for (Object obj : liwl) {
System.out.println(obj);
}
*/
}
}
Map-HashMap
HashMap的存取:
调用HashMap集合类的方法keySet(),获取到Map中所有键的Set集合,然后通过Set集合类的Iterator迭代Set集合的每个元素(键),最后调用HashMap的get()方法,获取值
import java.util.*;
public class Liwl {
public static void main(String[] args) {
HashMap<String,String> liwl = new HashMap<>();
liwl.put("001","liwanliang001");
liwl.put("002","liwanliang002");
Set keySet = liwl.keySet();
Iterator it = keySet.iterator();
while (it.hasNext()) {
Object key = it.next();
Object value = liwl.get(key);
System.out.println(key+":"+value);
}
}
}
另外一种方式:
获取集合中的所有映射关系,从映射关系取出键值对
import java.util.*;
public class Liwl {
public static void main(String[] args) {
HashMap<String,String> liwl = new HashMap<>();
liwl.put("001","liwanliang001");
liwl.put("002","liwanliang002");
Set entrySet = liwl.entrySet();
Iterator it = entrySet.iterator();
while ( it.hasNext() ) {
Map.Entry entry = (Map.Entry)it.next();
Object key = entry.getKey();
Object value = entry.getValue();
System.out.println(key+":"+value);
}
}
}
Map-Properties
输入输出
- IO输入输出
- 字节流
- 字节输入流 java.io.InputStream
- ByteArrayInputStream
- FileInputStream
- BufferedInpubStream
- DataInputStream
- FilterInputStream
- ObjectInputStream
- 字节输出流java.io.OutputStream
- ByteArrayOutputStream
- FileOutputStream
- FilterOutputStream
- BufferedOutputStream
- PrintStream
- DataInputStream
- ObjectInputStream
- 字节输入流 java.io.InputStream
- 字符流
- 字符输入流java.io.Reader
- 字符输出流java.io.Writer
- 字节流
字节流
文件的输出
对文件对象的读取
import java.io.*;
public class Liwl {
public static void main(String[] args) throws Exception {
FileInputStream input = new FileInputStream("liwl.txt");
int i = 0;
while (true){
i = input.read();
if ( i == -1 ){
break;
}
System.out.println(i);
}
input.close();
}
}
文件的输入
对文件对象的写入
import java.io.*;
public class Liwl {
public static void main(String[] args) throws Exception {
FileOutputStream output = null;
try {
output = new FileOutputStream("/root/liwl.txt");
String web = "nsccwx.cn";
byte[] arr = web.getBytes();
for ( int i = 0; i < arr.length; i++ ){
output.write(arr[i]);
}
} catch ( IOException e) {
//e.printStackTrace();
System.out.println("打开文件错误");
} finally {
if ( output != null ){
output.close();
}
}
}
}
文件的复制
import java.io.*;
public class Liwl {
public static void main(String[] args) throws Exception {
FileInputStream input = new FileInputStream("liwl.txt");
FileOutputStream output = new FileOutputStream("liwl_new.txt");
int i = 0;
long startTime = System.currentTimeMillis();
while ( ( i=input.read() ) != -1) {
output.write(i);
}
long endTime = System.currentTimeMillis();
System.out.println("复制文件时间:"+(endTime-startTime)+"毫秒");
input.close();
output.close();
}
}
字节流缓冲区
import java.io.*;
public class Liwl {
public static void main(String[] args) throws Exception {
FileInputStream input = new FileInputStream("dark.jpg");
FileOutputStream output = new FileOutputStream("dark_new.jpg");
byte[] buffer = new byte[1024];
int length = 0;
long startTime = System.currentTimeMillis();
while ( ( length = input.read(buffer) ) != -1) { //read方法可以读取字节数组,缓存区
output.write(buffer,0,length);
}
long endTime = System.currentTimeMillis();
System.out.println("复制文件时间:"+(endTime-startTime)+"毫秒");
input.close();
output.close();
}
}
字节缓冲流
public class Liwl {
public static void main(String[] args) throws Exception {
BufferedInputStream bufferInput = new BufferedInputStream(new FileInputStream("dark.jpg"));
BufferedOutputStream bufferOutput = new BufferedOutputStream(new FileOutputStream("dark_new.jpg"));
long startTime = System.currentTimeMillis();
int length;
while ( (length=bufferInput.read()) != -1 ){
bufferOutput.write(length );
}
long endTime = System.currentTimeMillis();
System.out.println("复制时间:"+(endTime-startTime)+"毫秒");
bufferInput.close();
bufferOutput.close();
}
}
字符流
字符流的读操作
import java.io.*;
public class Liwl {
public static void main(String[] args) throws Exception {
FileReader fileReader = new FileReader("liwl.txt");
int i;
while ( (i = fileReader.read()) !=-1 ) {
System.out.println((char) i);
}
fileReader.close();
}
}
字符流的写操作
import java.io.*;
public class Liwl {
public static void main(String[] args) throws Exception {
FileWriter w = new FileWriter("liwl.txt",true);
String name = "liwanliang";
w.write(name);
w.close();
}
}
字符流的缓冲流
import java.io.*;
public class Liwl {
public static void main(String[] args) throws Exception {
BufferedReader bfr = new BufferedReader(new FileReader("liwl.txt"));
BufferedWriter brw = new BufferedWriter(new FileWriter("liwl001.txt"));
String s = null;
while ( (s=bfr.readLine())!=null){
brw.write(s);
brw.newLine();
}
bfr.close();
brw.close();
}
}
转换流
字节流转换为字符流,或者字符流转为字节流
File类
多线程
线程的创建
通过继承Thread类
public class Liwl extends Thread{
public void run(){
for (int i=0; i<5; i++){
System.out.println("Liwl类的run()方法执行了");
}
}
public static void main(String[] args) {
Liwl liwl01 = new Liwl();
liwl01.start();
for(int i=0; i<5; i++){
System.out.println("主方法的main()执行了");
}
}
}
实现Runnable接口
public class Liwl implements Runnable{
public void run(){
for (int i=0; i<5; i++){
System.out.println("Liwl类的run()方法执行了");
}
}
public static void main(String[] args) {
Liwl liwl01 = new Liwl(); //创建实例对象
Thread thr = new Thread(liwl01); //传入实例对象,创建线程对象
thr.start(); //开启线程,执行线程对象的run方法
for(int i=0; i<5; i++){
System.out.println("主方法的main()执行了");
}
}
}
Runnable相对于Thread类:
- 适合多个程序代码相同的线程处理同一资源的情况
- 可以避免由于java的单继承特性特来的局限
线程的状态和转换
线程生命周期
- 开始:线程对象创建完毕
- 结束:run方法正常执行完毕,或者出现未捕获的异常或者错误
线程周期的五种状态
-
新建状态
线程对象创建以后,线程处于新建状态。处于新建状态的线程仅仅在java虚拟机分配了内存空间,不能运行
-
就绪状态
线程调用了start方法后,进入就绪状态。处于就绪状态的线程位于可运行池中,具备运行的条件,等待系统调度运行
-
运行状态
就绪状态获取CPU的执行权,并开始执行run方法时,线程处于运行状态。当系统分配的CPU时间到达时,转为就绪状态
-
阻塞状态
被人为挂起执行耗时的输入输出操作时,线程让出CPU,进入阻塞状态。阻塞原因解除后,进入就绪状态。
-
死亡状态
线程调用stop方法或者run方法执行结束后,线程处于死亡状态。
多线程同步
线程安全
同步代码块
同步方法
java注解
注解是代码的元数据,跟class,interface一样,也是一种类型。其作用:
- 编译检查
注解的定义形式
public @interface AnnotationName{
//基本数据类型
public int xxx() default xxx;
public String yyy() default xxx;
}
元注解概念作用
元注解,是注解类型的注解。如果把注解理解为标签 ,那元注解就是标签的标签,是一种特殊的标签,来给其他普通标签解释说明。
元注解种类:
-
@Retention 保留期
取值:
RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器编译源码成字节码之后,该注解被丢弃
RetentionPolicy.CLASS 注解只被保留在字节码中,不会被加载到JVM中
RetentionPolicy.RUNTIME 注解可以保留在程序运行时,会被加载到JVM中。程序运行时,可以获取到注解内容。
-
@Target 注解的目标
取值:
ElementType.ANNOTATION_TYPE 给一个注解类型注解
ElementType.CONSTRUCTOT 给构造方法注解
ElementType.FIELD 给属性注解
ElementType.LOCAL_VARIABLE 给局部变量注解
ElementType.METHOD 给方法注解
ElementType.PACKAGE 给一个包注解
ElementType.PARAMETER 给一个方法内的参数注解
ElementType.TYPE 给一个类型注解,比如类,接口,枚举
-
@Documented 注解包含到javadoc
-
@Inherited 注解的普通注解能被子类继承
-
@Repeatable 多重标签
解释:被Repeatable标注的普通注解,可用来多次注解同一个目标。如:
@interface LiwanLiangs { Liwanliang[] value(); } @Repeatable(Liwanliangs.class) @interface Liwanliang{ String name(); } @LiwanLiang("liwl01") @Liwanliang("liwl02") public class Others{ }
这段代码中,自定义注解Liwanliang用来多次注解类Others。而自定义注解Liwanliang是一个被元注解Repeatable注解的普通注解。元注解Repeatable传入了一个参数类——LiwanLiangs.class,它是一个容器注解。这个LiwanLiangs是一个用来存放其他注解的普通注解,按照注解的定义,LiwanLiangs必须有个一value属性,这个value属性是被Repeatable标注过的LiwanLiang注解的数组,即LiwanLiang[]
注解的属性
注解的属性,也叫做成员变量(注解也是类型)。
属性以“无参数方法”的形式类定义,属性的名字就是方法的名字,属性的返回值就是方法的返回值。属性的返回值,只能是8中基本数据类型,类,接口,注解,以及它们的数组。
属性的赋值:在注解括号内,以value=key的形式,多个属性用逗号隔开。属性可以有默认值,在属性方法括号后,使用default关键字指定。有默认值时,注解参数中可以省略书写。
java内置注解
这些注释是面向编辑器或者编译器的
@Deprecated
用来标记过时的元素,如过时的类,方法,变量等
@Override
提示子类重写父类中被@override修饰的方法
@SuppressWarnings
压制警告
@SafeVarargs
参数安全类型注解。提示开发者不要用参数做一些不安全的操作,它的存在会组织编译器产生unchecked这样的警告。
@FunctionlInterface
函数式接口注解。
注解的提取
注解需要通过java的反射机制来获取。
基本步骤:
-
首先通过Class对象的isAnnotationPresent()方法判断它是否应用了某个注解
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass){}
-
然后通过getAnnotation()方法获取Annotation对象
public < A extends Annotation> A getAnnotation(Class<A> annotationClass) {}
-
然后获取注解的属性值(调用属性方法)
注解应用实例—用来替换配置文件
自定义注解
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface LiwlAnnoDamo {
public String name();
public int age();
}
对一个类使用自定义注解
@LiwlAnnoDamo(age=30,name="liwanliang")
class Liwl {
private String name;
private int age;
public int getLiwlAge(){
return age;
}
public void setLiwlAge(int age){
this.age = age;
}
public String getLiwlName(){
return name;
}
public void setLiwlName(String name){
this.name = name;
}
}
创建注解解析器
class LiwlInfoUtil{
public static Liwl getLiwl(Class<?> clazz) throws Exception{
LiwlAnnoDamo lad = clazz.getAnnotation(LiwlAnnoDamo.class);
Liwl liwl = (Liwl)clazz.getDeclaredConstructor().newInstance();
liwl.setLiwlAge(lad.age());
liwl.setLiwlName(lad.name());
return liwl;
}
}
测试注解
public class LiwanLiangMain {
public static void main(String[] args) throws Exception {
Liwl liwl01 = LiwlInfoUtil.getLiwl(Liwl.class);
System.out.println("名字:"+liwl01.getLiwlName());
System.out.println("年纪:"+liwl01.getLiwlAge());
}
}