Java学习笔记
命令行运行 javac -encoding utf8 demo.java java demo
Java基础 注释 单行注释 单行注释使用//
public class HelloWorld { public static void main (String[] args) { System.out.println("hello world" ); } }
多行注释 多行注释使用/**/
public class HelloWorld { public static void main (String[] args) { System.out.println("hello world" ); } }
文档注释 Javadoc:文档注释
标识符和关键字 关键字
Java关键字类别
Java关键字
关键字含义
访问控制
private
一种访问控制方式:私用模式,访问控制修饰符,可以应用于类、方法或字段(在类中声明的变量)
访问控制
protected
一种访问控制方式:保护模式,可以应用于类、方法或字段(在类中声明的变量)的访问控制修饰符
访问控制
public
一种访问控制方式:共用模式,可以应用于类、方法或字段(在类中声明的变量)的访问控制修饰符。
类、方法和变量修饰符
abstract
表明类或者成员方法具有抽象属性,用于修改类或方法
类、方法和变量修饰符
class
声明一个类,用来声明新的Java类
类、方法和变量修饰符
extends
表明一个类型是另一个类型的子类型。对于类,可以是另一个类或者抽象类;对于接口,可以是另一个接口
类、方法和变量修饰符
final
用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量
类、方法和变量修饰符
implements
表明一个类实现了给定的接口
类、方法和变量修饰符
interface
接口
类、方法和变量修饰符
native
用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的
类、方法和变量修饰符
new
用来创建新实例对象
类、方法和变量修饰符
static
表明具有静态属性
类、方法和变量修饰符
strictfp
用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范
类、方法和变量修饰符
synchronized
表明一段代码需要同步执行
类、方法和变量修饰符
transient
声明不用序列化的成员域
类、方法和变量修饰符
volatile
表明两个或者多个变量必须同步地发生变化
程序控制
break
提前跳出一个块
程序控制
continue
回到一个块的开始处
程序控制
return
从成员方法中返回数据
程序控制
do
用在do-while循环结构中
程序控制
while
用在循环结构中
程序控制
if
条件语句的引导词
程序控制
else
用在条件语句中,表明当条件不成立时的分支
程序控制
for
一种循环结构的引导词
程序控制
instanceof
用来测试一个对象是否是指定类型的实例对象
程序控制
switch
分支语句结构的引导词
程序控制
case
用在switch语句之中,表示其中的一个分支
程序控制
default
默认,例如:用在switch语句中,表明一个默认的分支。Java8 中也作用于声明接口函数的默认实现
错误处理
try
尝试一个可能抛出异常的程序块
错误处理
catch
用在异常处理中,用来捕捉异常
错误处理
throw
抛出一个异常
错误处理
throws
声明在当前定义的成员方法中所有需要抛出的异常
包相关
import
表明要访问指定的类或包
包相关
package
包
基本类型
boolean
基本数据类型之一,声明布尔类型的关键字
基本类型
byte
基本数据类型之一,字节类型
基本类型
char
基本数据类型之一,字符类型
基本类型
double
基本数据类型之一,双精度浮点数类型
基本类型
float
基本数据类型之一,单精度浮点数类型
基本类型
int
基本数据类型之一,整数类型
基本类型
long
基本数据类型之一,长整数类型
基本类型
short
基本数据类型之一,短整数类型
基本类型
null
空,表示无值,不能将null赋给原始类型(byte、short、int、long、char、float、double、boolean)变量
基本类型
true
真,boolean变量的两个合法值中的一个
基本类型
false
假,boolean变量的两个合法值之一
变量引用
super
表明当前对象的父类型的引用或者父类型的构造方法
变量引用
this
指向当前实例对象的引用,用于引用当前实例
变量引用
void
声明当前成员方法没有返回值,void可以用作方法的返回类型,以指示该方法不返回值
保留字
goto
保留关键字,没有具体含义
保留字
const
保留关键字,没有具体含义,是一个类型修饰符,使用const声明的对象不能更新
所有标识符应该以字母A-Z
或a-z
、美元符$
、或下划线_
开始
首字母之后可以是字母、美元符、下划线或数字的组合
标识符是大小写敏感的
可以使用中文命名,但不建议
不能使用关键字作为变量名或方法名
数据类型
强类型语言:强制类型定义,要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用
弱类型语言:类型可以被忽略,一个变量被定义类型,该变量可以根据环境变化自动进行转换,不需要经过显性强制转换
java的数据类型分为两大类:
注意:long型赋值时要加上L(大写),float型要加上f或F
public class Demo02 { public static void main (String[] args) { byte n1=10 ; int n2=20 ; short n3=30 ; long n4= 30L ; float n5=40.2F ; double n6=12.44 ; char n7='好' ; String n8="你好" ; boolean n9=true ; System.out.println(n9); } }
注意:八进制要在前面加0,十六进制要加0x,二进制加0b;
尽量不要使用浮点数进行比较,使用BigDecimal类
public class Demo03 { public static void main (String[] args) { int i=10 ; int i1=010 ; int i2=0x10 ; int i3=0b10 ; System.out.println(i); System.out.println(i1); System.out.println(i2); System.out.println(i3); float i4=0.1F ; double i5=1.0 /10 ; System.out.println(i4==i5); float i6=123344443342342245f ; float i7=i6+1 ; System.out.println(i6==i7); char a1='a' ; char a2='中' ; System.out.println(a1); System.out.println((int )a1); System.out.println(a2); System.out.println((int )a2); char a3='\u0061' ; System.out.println(a3); System.out.println("hello\tworld" ); String sa=new String("hello world" ); String sb=new String("hello world" ); System.out.println(sa==sb); String sc="hello world" ; String sd="hello world" ; System.out.println(sc==sd); boolean flag=true ; if (flag){ System.out.println("你好" ); } } }
类型转换 由于java是强类型语言,所以进行有些计算时需要类型转换。
类型转换分为:
public class Demo04 { public static void main (String[] args) { int i=128 ; byte b=(byte )i; System.out.println(i); System.out.println(b); double d=i; System.out.println(d); System.out.println((int )23.6 ); System.out.println((int )45.88f ); char c='a' ; int i1=c+1 ; System.out.println(i1); } }
public class Demo05 { public static void main (String[] args) { int money=10_0000_0000 ; int years=20 ; int total1=money*years; long total2=money*years; long total3=money*((long )years); System.out.println(total1); System.out.println(total2); System.out.println(total3); } }
变量 public class Demo06 { static int test=10 ; String name; int age; public static void main (String[] args) { int a=1 ; int b=2 ; int c=3 ; String name="hello world" ; char x='X' ; double pi=3.14 ; System.out.println(a); Demo06 demo06 =new Demo06(); System.out.println(demo06.age); System.out.println(demo06.name); System.out.println(test); } public void add () { } }
基本运算符 package operator;public class Demo05 { public static void main (String[] args) { boolean a=true ; boolean b=false ; System.out.println("a&&b:" +(a&&b)); System.out.println("a||b:" +(a||b)); System.out.println("!(a&&b)" +!(a&&b)); int c=5 ; boolean d=(c<4 )&&(c++<4 ); System.out.println(c); System.out.println(d); int e=6 ; boolean f=(e>4 )||(e++>4 ); System.out.println(e); System.out.println(f); System.out.println(2 <<3 ); } }
package operator;public class Demo07 { public static void main (String[] args) { int a=10 ; int b=20 ; a+=b; System.out.println(a); System.out.println("" +a+b); System.out.println(("" +(a+b)).getClass().toString()); } }
package operator;public class Demo08 { public static void main (String[] args) { int score=80 ; String type=score<60 ?"不及格" :"及格" ; System.out.println(type); } }
包机制
为了更好地组织类, Java 提供了包机制,用于区别类名的命名空间。 包语句的语法格式为: package pkg1[. pkg2[. pkg..]]; 一般利用公司域名倒置作为包名: www.baidu.com com.baidu.www 为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包。使用”import”语句可完成此功能: import package1[.package..].(classname|*);
注意:import一定要在package下面
Javadoc
javadoc命令是用来生成自己API文档的
使用命令行生成
使用idea生成
Java流程控制 用户交互scanner
java.util.scanner是Java5的新特征,我们可以通过scanner类获取用户的输入。
基本语法:
Scanner s=new Scanner(System.in);
通过Scanner类的next()和nextLine()方法获取输入的字符串,在读取前一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据。
next()和hasNext()配套使用;nextLine()hasNextLine()配套使用。
hasNext()
方法会判断接下来是否有非空字符.如果有,则返回true
,否则返回false
hasNextLine()
方法会根据行匹配模式去判断接下来是否有一行(包括空行),如果有,则返回true
,否则返回false
next():
一定要读取到有效字符后才可以结束输入。
对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
next() 不能得到带有空格的字符串。
nextLine():
以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符。
可以获得空白。
package com.idefun.scanner;import java.util.Scanner;public class Demo01 { public static void main (String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("使用next方式接收:" ); if (scanner.hasNext()){ String str=scanner.next(); System.out.println("输出:" +str); } scanner.close(); } }
package com.idefun.scanner;import java.util.Scanner;public class Demo02 { public static void main (String[] args) { Scanner scanner =new Scanner(System.in); System.out.println("使用nextLine方式接收:" ); if (scanner.hasNextLine()){ String str=scanner.nextLine(); System.out.println("输出:" +str); } scanner.close(); } }
选择结构 if选择结构 package com.idefun.struct;import java.util.Scanner;public class Demo03 { public static void main (String[] args) { Scanner scanner =new Scanner(System.in); System.out.println("请输入成绩:" ); float score=0.0f ; score=scanner.nextFloat(); if (score>=60 && score<=100 ){ System.out.println("及格" ); } else if (score<60 && score>=0 ){ System.out.println("不及格" ); } else { System.out.println("错误" ); } scanner.close(); } }
switch选择结构 package com.idefun.struct;public class Demo04 { public static void main (String[] args) { char grade='C' ; switch (grade){ case 'A' : System.out.println("优秀" ); break ; case 'B' : System.out.println("良好" ); break ; case 'C' : System.out.println("及格" ); break ; case 'D' : System.out.println("再接再厉" ); break ; default : System.out.println("查询无果" ); } } }
package com.idefun.struct;public class Demo05 { public static void main (String[] args) { String name="test" ; switch (name){ case "htl" : System.out.println("htl" ); break ; case "gee" : System.out.println("gee" ); break ; default : System.out.println("test" ); } } }
循环结构 while循环 package com.idefun.struct;public class Demo06 { public static void main (String[] args) { int i=0 ; int sum=0 ; while (i<100 ){ i++; sum+=i; } System.out.println(sum); } }
do while循环 package com.idefun.struct;public class Demo07 { public static void main (String[] args) { int i=0 ; int sum=0 ; do { i++; sum+=i; }while (i<100 ); System.out.println(sum); } }
for循环
小技巧:在idea中输入100.for
并回车即可生成0-100for循环
死循环: for(;;){}
package com.idefun.struct;public class Demo08 { public static void main (String[] args) { int sum=0 ; for (int i = 0 ; i <= 100 ; i++) { sum+=i; } System.out.println(sum); } }
package com.idefun.struct;public class Demo09 { public static void main (String[] args) { for (int i = 1 ; i <= 1000 ; i++) { if (i%5 ==0 ){ System.out.print(i+"\t" ); } if (i%15 ==0 ){ System.out.println(); } } } }
package com.idefun.struct;public class Demo10 { public static void main (String[] args) { for (int i=1 ;i<10 ;i++){ for (int j=1 ;j<=i;j++){ System.out.print(j+"*" +i+"=" +(i*j)+"\t" ); if (j==i){ System.out.println(); } } } } }
增强for循环 package com.idefun.struct;public class Demo11 { public static void main (String[] args) { int [] nums={10 ,20 ,30 ,40 ,50 }; for (int x:nums){ System.out.println(x); } } }
终止循环
打印101-105之间的质数(注意比较下面两个代码)
package com.idefun.struct;public class Demo12 { public static void main (String[] args) { int n=0 ; for (int i=101 ;i<150 ;i++){ int flag=0 ; for (int j=2 ;j<=i/2 ;j++){ if (i%j==0 ){ flag=1 ; break ; } } if (flag==0 ){ System.out.print(i+"\t" ); } } } }
package com.idefun.struct;public class Demo13 { public static void main (String[] args) { int n=0 ; outer:for (int i=101 ;i<150 ;i++){ for (int j=2 ;j<=i/2 ;j++){ if (i%j==0 ){ continue outer; } } System.out.print(i+"\t" ); } } }
Java方法 package com.idefun.method;public class Demo01 { public static void main (String[] args) { int sum=add(1 ,3 ); System.out.println(sum); } public static int add (int a, int b) { return a+b; } }
static的作用是,将属性或者方法修饰为该类的共享成员,即这个属性或方法是该类实例化的所有对象之间共享的,不为某个实例对象所有,static属性或方法是存储在内存的公共区,一个类中,一个static变量只会有一个内存空间,虽然有多个类实例,但这些类实例中的这个static变量会共享同一个内存空间。
方法重载 package com.idefun.method;public class Demo03 { public static void main (String[] args) { double a=10.0 ; int b=5 ; System.out.println(max(a,b)); } public static int max (int a,int b) { return a>b?a:b; } public static double max (double a,double b) { return a>b?a:b; } }
可变参数
在方法声明中,在指定参数类型后加一个省略号(…)。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
package com.idefun.method;public class Demo05 { public static void main (String[] args) { Demo05 demo05=new Demo05(); demo05.test(1 ,3 ,45 ); demo05.test(new int []{2 ,4 ,7 }); } public void test (int ... i) { for (int k : i) { System.out.println(k); } } }
递归
递归结构包括两个部分:
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
递归体:什么时候需要调用自身方法。
递归要找好终止条件.
package com.idefun.method;public class Demo06 { public static void main (String[] args) { Demo06 demo06=new Demo06(); System.out.println(demo06.factorial(3 )); } public int factorial (int n) { if (n==1 ){ return 1 ; } else { n*=factorial(n-1 ); return n; } } }
Java数组 数组声明创建
声明数组的语法:
dataType[] array; //首选方法 dataTyep array[];
创建数组语法:
dataType array=new dataType(arraySize);
三种初始化
静态初始化 int[] a={1,2,3}; Man[] mans={new Man(1,1),new Man(2,1)};
动态初始化 int[] a=new int[2]; a[0]=1; a[1]=2;
默认初始化
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也按照实例变量同样的方式被隐式初始化。
package com.idefun.array;public class Demo01 { public static void main (String[] args) { int [] a={1 ,2 ,3 ,4 }; System.out.println(a[2 ]); int [] b=new int [10 ]; b[0 ]=10 ; System.out.println(b[0 ]); System.out.println(b[4 ]); System.out.println(b[8 ]); } }
数组的四个基本特点
其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
其元素必须是相同类型,不允许出现混合类型。
数组中的元素可以是任何数据类型,包括基本类型和引用类型。
数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量.
数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
ArrayIndexOutOfBoundsException:数组下标越界异常!
二维数组
package com.idefun.array;public class Demo02 { public static void main (String[] args) { int [][] array={{1 ,2 },{3 ,4 },{5 ,6 }}; System.out.println(array.length); System.out.println(array[0 ].length); for (int i=0 ;i<array.length;i++){ for (int j=0 ;j<array[i].length;j++){ System.out.println(array[i][j]); } } } }
Arrays类
数组的工具类java.util.Arrays
由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。
Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而”不用”使用对象来调用(注意:是”不用”而不是”不能”)
具有以下常用功能:
给数组赋值:通过fill方法。
对数组排序:通过sort方法,按升序。
比较数组:通过equals方法比较数组中元素值是否相等。
查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。
稀疏数组
当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式是:
记录数组一共有几行几列,有多少个不同值
把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
package com.idefun.array;public class Demo05 { public static void main (String[] args) { int [][] array1=new int [11 ][11 ]; array1[1 ][2 ]=1 ; array1[2 ][3 ]=2 ; System.out.println("原始数组:" ); for (int [] ints:array1){ for (int j:ints){ System.out.print(j+"\t" ); } System.out.println(); } int sum=0 ; for (int i = 0 ; i < 11 ; i++) { for (int i1 = 0 ; i1 < 11 ; i1++) { if (array1[i][i1]!=0 ){ sum++; } } } System.out.println("有效值个数:" +sum); int [][] array2=new int [sum+1 ][3 ]; array2[0 ][0 ]=11 ; array2[0 ][1 ]=11 ; array2[0 ][2 ]=sum; int n=1 ; for (int i = 0 ; i < 11 ; i++) { for (int i1 = 0 ; i1 < 11 ; i1++) { if (array1[i][i1]!=0 ){ array2[n][0 ]=i; array2[n][1 ]=i1; array2[n][2 ]=array1[i][i1]; n++; } } } System.out.println("稀疏数组" ); for (int [] ints : array2) { for (int anInt : ints) { System.out.print(anInt+"\t" ); } System.out.println(); } System.out.println("还原" ); int [][] array3=new int [array2[0 ][0 ]][array2[0 ][1 ]]; for (int i = 1 ; i <=array2[0 ][2 ] ; i++) { array3[array2[i][0 ]][array2[i][1 ]]=array2[i][2 ]; } for (int [] ints:array3){ for (int j:ints){ System.out.print(j+"\t" ); } System.out.println(); } } }
面向对象编程 在同一个类中
对于静态方法,其他的静态或非静态方法都可以直接调用它。
对于非静态方法,其他的非静态方法是可以直接调用它的,但是其他静态方法只有通过对象才能调用它。静态方法不能被非静态方法覆盖。
在不同类中
静态方法,则通过类名与对象都可以调用(但通过对象的方式不建议使用,因为它属于非静态调用的方式)
非静态方法,则只能通过对象才可以调用它
package com.idefun.oop;public class Demo03 { public static void main (String[] args) { Demo03 demo03=new Demo03(); demo03.a(); } public void a () { System.out.println("a" ); b(); } public void b () { System.out.println("b" ); } public static void c () { System.out.println("c" ); } }
package com.idefun.oop;public class Demo04 { public static void main (String[] args) { Demo03.c(); Demo03 demo03=new Demo03(); demo03.a(); demo03.c(); } }
值传递和引用传递 package com.idefun.oop;public class Demo05 { public static void main (String[] args) { int a=1 ; System.out.println(a); change(a); System.out.println(a); } public static void change (int a) { a=10 ; } }
package com.idefun.oop;public class Demo06 { public static void main (String[] args) { Person person=new Person(); System.out.println(person.name); change(person); System.out.println(person.name); } public static void change (Person person) { person.name="hello" ; } } class Person { String name; }
创建和初始化对象
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
必须和类的名字相同
必须没有返回类型,也不能写void
一旦定义有参构造,就要显示定义无参构造
封装
使用快捷键Alt+Insert可快速生成get和set方法
package com.idefun.oop.demo04;public class Student { private String name; private int id; private int age; private char sex; public String getName () { return this .name; } public void setName (String name) { this .name=name; } public int getId () { return id; } public void setId (int id) { this .id = id; } public char getSex () { return sex; } public void setSex (char sex) { this .sex = sex; } public int getAge () { return age; } public void setAge (int age) { if (0 <=age && age<=120 ){ this .age = age; }else { System.out.println("error" ); } } }
package com.idefun.oop;import com.idefun.oop.demo04.Student;public class Applicatipn { public static void main (String[] args) { Student s1=new Student(); s1.setName("tom" ); System.out.println(s1.getName()); s1.setAge(999 ); System.out.println(s1.getAge()); } }
继承
java中只有单继承没有多继承,接口可以多继承
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
子类无法继承父类私有属性。
在java中,所有的类都默认直接或间接继承Object类
super
super()和this()都必须放在构造函数第一行,所有不能同时出现。
package com.idefun.oop.demo05;public class Person { protected String name="test1" ; public Person () { System.out.println("Person无参执行了" ); } public void print () { System.out.println("Person" ); } }
package com.idefun.oop.demo05;public class Student extends Person { private String name="test2" ; public Student () { System.out.println("Student无参执行了" ); } public void test (String name) { System.out.println(name); System.out.println(this .name); System.out.println(super .name); } public void print () { System.out.println("Student" ); } public void test1 (String name) { print(); this .print(); super .print(); } }
package com.idefun.oop;import com.idefun.oop.demo05.Student;public class Applicatipn { public static void main (String[] args) { Student student=new Student(); } }
方法重写
重写:需要有继承关系,子类重写父类的方法!
方法名必须相同
参数列表列表必须相同
修饰符:范围可以扩大但不能缩小:public >protected>default>private
抛出的异常:范围,可以被缩小,但不能扩大: ClassNotFoundException —> Exception(大)
多态
多态存在的条件:
有继承关系
子类重写父类方法
父类引用指向子类对象
多态是方法的多态,属性没有多态
package com.idefun.oop.demo07;public class Person { public void run () { System.out.println("Person->run" ); } }
package com.idefun.oop.demo07;public class Student extends Person { @Override public void run () { System.out.println("Student->run" ); } public void eat () { System.out.println("Student->eat" ); } }
package com.idefun.oop.demo07;public class Application { public static void main (String[] args) { Student s1=new Student(); Person s2=new Student(); Object s3=new Student(); s2.run(); s1.run(); } }
instanceof和类型转换 instanceof package com.idefun.oop.demo07;public class Person { public void run () { System.out.println("Person->run" ); } }
package com.idefun.oop.demo07;public class Student extends Person { }
package com.idefun.oop.demo07;public class Teacher extends Person {}
package com.idefun.oop.demo07;public class Application { public static void main (String[] args) { Object object = new Student(); System.out.println(object instanceof Student); System.out.println(object instanceof Person); System.out.println(object instanceof Teacher); System.out.println(object instanceof Object); System.out.println(object instanceof String); System.out.println("==================" ); Person person = new Student(); System.out.println(person instanceof Student); System.out.println(person instanceof Person); System.out.println(person instanceof Object); System.out.println(person instanceof Teacher); Student student = new Student(); System.out.println("==================" ); System.out.println(student instanceof Student); System.out.println(student instanceof Person); System.out.println(student instanceof Object); } }
类型转换 package com.idefun.oop.demo08;public class Person { public void run () { System.out.println("Person->run" ); } }
package com.idefun.oop.demo08;public class Student extends Person { public void go () { System.out.println("Student->go" ); } }
package com.idefun.oop.demo08;public class Application { public static void main (String[] args) { Person student = new Student(); ((Student) student).go(); } }
static详解
通过final修饰的类无法被继承
package com.idefun.oop.demo09;public class Student { private static int age; private double score; public void run () { System.out.println("run" ); } public static void go () { System.out.println("go" ); } public static void main (String[] args) { Student student = new Student(); System.out.println(Student.age); System.out.println(student.age); System.out.println(student.score); Student.go(); student.go(); student.run(); } }
package com.idefun.oop.demo09;public class Person { { System.out.println("匿名代码块" ); } static { System.out.println("静态代码块" ); } public Person () { System.out.println("构造方法" ); } public static void main (String[] args) { Person person1 = new Person(); System.out.println("==============" ); Person person2 = new Person(); } }
package com.idefun.oop.demo09;import static java.lang.Math.random;public class Test { public static void main (String[] args) { System.out.println(random()); } }
抽象类
抽象类的特征:
不可被实例化
抽象类是有构造器的(所有类都有构造器)
抽象方法所在的类,一定是抽象类(因为抽象方法是没有方法体的,如果所在的类不是抽象类,那么该类可以实例化对象,调用抽象方法,然后无方法体去具体实现功能,则矛盾)
抽象类可以没有抽象方法的
抽象方法的特征:
格式,没有方法体,包括{ },例如 public abstract void dink();
抽象方法只保留方法的功能,具体的执行,交给继承抽象类的子类,由子类重写改抽象方法
如果子类继承抽象类,并重写了父类的所有的抽象方法,则此子类不是抽象类,可以实例化的
如果子类继承抽象类,没有重写父类中所有的抽象方法,意味着子类中还有抽象方法,那么此子类必须必须声明为抽象的。
package com.idefun.oop.demo10;public abstract class Action { public abstract void doSomething () ; public void run () { System.out.println("run" ); } }
package com.idefun.oop.demo10;public class Test extends Action { @Override public void doSomething () { } }
接口
接口可以看成是一种特殊的类,只能用 interface 关键字修饰。
Java 中的接口具有以下几个特点:
接口中可以包含变量和方法,变量被隐式指定为 public static final,方法被隐式指定为 public abstract(JDK 1.8 之前)。
接口支持多继承,即一个接口可以继承(extends)多个接口,间接解决了 Java 中类不能多继承的问题。
一个类可以同时实现多个接口,一个类实现某个接口则必须实现该接口中的抽象方法,否则该类必须被定义为抽象类。
package com.idefun.oop.demo11;public interface Test { int AGE=49 ; void add (String name) ; void delete (String name) ; void update (String name) ; void query (String name) ; }
package com.idefun.oop.demo11;public interface Test2 { void timer () ; }
package com.idefun.oop.demo11;public class TestImpl implements Test ,Test2 { @Override public void add (String name) { System.out.println("add" ); } @Override public void delete (String name) { System.out.println(); } @Override public void update (String name) { } @Override public void query (String name) { } @Override public void timer () { } }
内部类
package com.idefun.oop.demo12;public class Outer { private int id=10 ; public void out () { System.out.println("outer" ); } class Inner { public void in () { System.out.println("inner" ); } public void getId () { System.out.println(id); } } }
package com.idefun.oop.demo12;public class Application { public static void main (String[] args) { Outer outer = new Outer(); Outer.Inner inner=outer.new Inner () ; outer.out(); inner.in(); inner.getId(); } }
静态内部类不能访问外部属性和方法
package com.idefun.oop.demo12;public class Outer { private int id=10 ; public void out () { System.out.println("outer" ); } public void method () { class B { } } public static class Inner { public void in () { System.out.println("inner" ); } } } class A {}
package com.idefun.oop.demo12;public class Test { public static void main (String[] args) { new Apple().eat(); new UserService(){ @Override public void hello () { System.out.println("hello" ); } }; } } class Apple { public void eat () { System.out.println("apple" ); } } interface UserService { void hello () ; }
异常
检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。 在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。
Error
Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。
还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。
Exception
这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生
Error和Exception的区别: Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程; Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。
异常处理机制
抛出异常
捕获异常
异常处理五个关键字
try、catch、finally、throw、throws
idea可使用Ctrl+Alt+T选择语句包裹
package com.idefun.exception;public class Demo01 { public static void main (String[] args) { int a=1 ; int b=0 ; try { System.out.println(a/b); } catch (Error e){ System.out.println("Error" ); } catch (Exception e){ System.out.println("Exception" ); } catch (Throwable e){ System.out.println("Throwable" ); } finally { System.out.println("finally" ); } } public void a () {b();} public void b () {a();} }
package com.idefun.exception;public class Demo02 { public static void main (String[] args) { int a=1 ; int b=0 ; try { if (b==0 ){ throw new ArithmeticException(); } System.out.println(a/b); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("finally" ); } } }
package com.idefun.exception;public class Demo03 { public static void main (String[] args) { try { new Demo03().test(1 ,0 ); } catch (ArithmeticException e) { e.printStackTrace(); } } public void test (int a,int b) throws ArithmeticException { if (b==0 ){ throw new ArithmeticException(); } System.out.println(a/b); } }
自定义异常
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
在程序中使用自定义异常类,大体可分为以下几个步骤:
创建自定义异常类。
在方法中通过throw关键字抛出异常对象。
如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
在出现异常方法的调用者中捕获并处理异常。
多线程 线程创建
Thread
自定义线程类继承Thread类
重写run()方法,编写线程执行体
创建线程对象,调用start()方法启动线程(线程开启不一定立即执行,由CPU调度)
package com.idefun.multithreading;import org.apache.commons.io.FileUtils;import java.io.File;import java.io.IOException;import java.net.URL;public class Demo02 extends Thread { private String url; private String name; public Demo02 (String url,String name) { this .url=url; this .name=name; } @Override public void run () { WebDownloader webDownloader=new WebDownloader(); System.out.println("正在下载" +name); webDownloader.downloader(this .url,this .name); } public static void main (String[] args) { Demo02 t1 = new Demo02("http://pic.bizhi360.com/bpic/7/10607.jpg" ,"1.jpg" ); Demo02 t2 = new Demo02("http://pic.bizhi360.com/litimg/10589.jpg" ,"2.jpg" ); Demo02 t3 = new Demo02("http://pic.bizhi360.com/litimg/10572.jpg" ,"3.jpg" ); t1.start(); t2.start(); t3.start(); } } class WebDownloader { public void downloader (String url,String name) { try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("downloader异常" ); } } }
runnable