目录
一、输出输入语句
(1)输出后换行
System.out.println();
(2)输出后不换行
System.out.print();
(3)常用输出
System.out.println(11); //整数
System.out.println(-11); //负数
System.out.println(-11.11); //小数
System.out.println('\t'); //缩进一个tab
System.out.println('A'); //单引号一个字符
System.out.println("abc"); //双引号一个字符串
System.out.println(true); //布尔值
System.out.println('\n'); //换行
(4) 输入语句
Scanner sc = new Scanner(System.in);
String a = sc.next(); //读取输入的下一个单词,以空格作为分隔符
String b = sc.nextLine(); //读取输入的下一行
int c = sc.nextInt();
double d = sc.nextDouble();
二、数据类型
1、常见数据类型
(1)整数类型:byte-1个字节,short-2个字节,int-4个字节,long-8个字节
1_1 ----> 11
(2)浮点数类型:float-4个字节,double-8个字节
1.1E2 ----> 110.0 1.1e-2 ----> 0.011 .11 ----> 0.11
(3)字符类型:char-2个字节
可以存放:字符,数字,转义字符
(4)布尔类型: boolean-1个字节
java中不可以用0或非0表示真假,只能用true和false
2、标识符
用于命名,由字母,数字,下划线等组成。
(1)不能用数字开头
(2)不能是关键字和保留字
(3)区分大小写
3、变量
变量要定义声明才能使用,全局变量有默认值,局部变量没有默认值要进行初始化
全局变量可以加修饰符,局部变量不可以加修饰符
(1)局部变量如果可以从变量的初始值推断出他的类型,只需要使用关键字var而无需指定类型
int first;
var second = 1;
(2)a和b都是局部变量,不能定义同名变量
int a = 1;
double b;
b = 1.0;
(3)虽然在long的范围,但整数字面量默认int类型,超过int的范围,要在后面加l或L
long c = 111111111111111L;
(4)虽然在float的范围,但小数字面量默认double类型,要在后面加f或F
float d = 99.8F;
4、类型转换
byte -> short -> int -> long -> float ->double char -> int -> long -> float ->double
(1)类型范围小的变量,可以直接赋值给类型范围大的变量
short g = 1;
int h=g;
(2)表达式的最终类型由最高类型决定
short g = 1;
double i = 1.0;
System.out.println(i+g);
输出:
2.0
(3)byte,short,char不能相互转换,是直接转换为int类型参与运算的
byte j = 1;
int k = j + g;
5、强制转换数据类型
(数据类型)变量
byte l = (byte) k;
三、基本运算
(1)基本运算符:+ - * / %
int a = 10;
int b = 3;
System.out.println((double)a / b);
System.out.println(a * 1.0 / b);
输出:
3.3333333333333335
3.3333333333333335
遇到正负数取余,只需看被除数是否为正数
System.out.println(3%2);
System.out.println(3%-2);
System.out.println(-3%2);
System.out.println(-3%-2);
输出:
1
1
-1
-1
(2)连接符:字符串运算时,"+"作为连接符
从左到右,能算则算,算不了连接
System.out.println("abc"+'a');
System.out.println("abc"+a);
System.out.println(5+'a'+"a");
输出:
abca
abc10
102a
(3)自增,自减:++ --
c++; 等价于 c = (c的数据类型) (c+1);
int c = 1;
c = c++;
System.out.println(c);
输出结果:
1
int c = 1;
c = ++c;
System.out.println(c);
输出结果:
2
(4)赋值运算符:= += -= *= /= %=
d += e; 等价于 d = (d的数据类型) (d+e);
d += e;
(5)关系运算符(返回布尔值):== != > < >= <=
==:俩个都为基本类型,判断值是否相等。都为引用类型,判断地址是否相等。一个基本类型一个引用类型,判断值是否相等。
(6)逻辑运算符 (返回布尔值):& | ! ^ && ||
^:不同时为true,相同时为false
&:右边都执行
|:右边都执行
&&:左边false右边不执行
||:左边true右边不执行
(7)三元运算符:条件表达式?a:b
int f = 10;
int g = 5;
int h = 1;
System.out.println(g > f ? g : f);
System.out.println(h > g ? h > f ? h : f : g > f ? g : f);
输出:
10
10
四、字符串
String s1 = "字符串";
String s2;
s2 = "字符串";
String s3 = new String("字符串");
String s4 = new String();
s4 = "字符串";
char[] chars = {'a','b','c'};
String s5 = new String(chars);
byte[] bytes = {97,98,99};
String s6 = new String(bytes); //整数转换为字符成字符串对象,abc
(1)字符串的字符使用Unicode字符编码,一个字符两个字节
(2)字符串本质是字符数组,String类有成员private final char value[ ]; 用于存放字符串的内容
(3)String s1 = "字符串"; s1指向常量池的"字符串"数据空间,如果没有则创建后再指向,s1最终指向的是常量池的空间地址
(4)String s3 = new String("字符串"); 先在堆中创建value,value指向常量池的"字符串"数据空间,如果没有则创建后再指向,s3最终指向的是堆中value的地址
(5)不可变字符串:不可以修改字符串中的单个字符,String变量每次修改都是产生并指向新的字符串对象,原来的字符串对象是没有改变的
1、拼接
(1)字符串与字符串拼接
String s1 = "ab" + "cd"; //只创建一个对象,等价于String s3 = "abcd";
String s2 = "ab" + s1;
String s3 = s1 + s2; //s3指向堆中的value
(2)字符串与非字符串拼接:非字符串会转换成字符串
String sentence3 = sentence1 + 1;
2、空串与null串
(1)空串:"" 长度:0 内容:空
检查一个字符串是否为空
if (sentence1.equals(""))
if (sentence1.length()==0)
(2)null串:表示目前没有任何对象与该变量关联
检查一个字符串是否为null
if (sentence1==null)
3、常用方法
(1)获取字符串长度:变量名.length();
int n = sentence.length();
(2)检查字符串是否相等:
equals方法:字符串1.equals(字符串2); 可以是字符串变量也可以是字符串字面量
sentence1.equals(sentence2);
"abcd".equals(sentence1);
sentence1.equals("abcd");
equalsIgnoreCase方法:字符串1.equalsIgnoreCase(字符串2);
"HELLO".equalsIgnoreCase("hello");
(3)获取某个位置的字符:变量名.charAt(索引);
char ch = sentence.charAt(1);
(4)字符串转换成字符数组:变量名.toCharArray();
char[] chs = sentence.toCharArray();
(5)获取字符或字符串在字符串中第一次出现的索引:变量名.indexOF(); 找不到返回-1
int i = sentence.indexOf('a');
获取字符或字符串在字符串中最后一次出现的索引:变量名.lastIndexOF();
int i = sentence.lastLndexOf("abc");
(6)获取子串:
变量名.substring(a,b); 范围:从a开始,到b结束,不包括b
String sen = sentence.substring(1,2);
变量名.substring(a); 范围:从a到结束
String sen = sentence.substring(1);
(7)获取替换字符串: 变量名.replace("需要前的字符串","替换后的字符串");
String sen = sentence.replace("ab","cd");
(8)字符串转换大小写:变量名.toLowerCase(); 变量名.toUpperCase();
String s1 = sentence.toLowerCase();
String s2 = sentence.toUpperCase();
(9)拼接字符串: 变量名.concat();
String s1 ="abcd";
s1 = s1.concat("ef").concat("g");
(10)比较两个字符串的大小:变量名1.compareTo(变量名2);
从第一个字符开始比较ASCII码值,发现第一个不同字符时,返回变量名1的字符值减去变量名2的字符值,如果长度不相等时,如果比较完较短字符串的所有字符后都相等,返回变量名1的字符串长度减去变量名2的字符串长度
String sentence1 = "ab";
String sentence2 = "cd";
int n = sentence1.compareTo(sentence2);
(11)判断是否包含关键字 :变量名.contains("需要判断的字符串");
boolean n = sentence.contains("字符串");
(12)判断以什么字符串开始:变量名.startsWith("需要判断的字符串");
boolean n = sentence.startsWith("字符串");
(13)按照某个字符把字符串分割成字符串数组返回:变量名.split("分割字符");
String sentence = "字符串1,字符串2,字符串3";
String[] sentences = sentence.split(",");
for (int i = 0; i < sentences.length; i++) {
System.out.println(sentences[i]);
}
输出结果:
字符串1
字符串2
字符串3
五、数组
1、动态初始化定义数组
数据类型[ ] 数组名 = new 数据类型[长度];
一旦创建了数组,就不能再改变它的长度
int[] number1 = new int[3]; //默认数组元素值为0,0.0,false,null
int[] number1;
number1 = new int[3];
2、静态初始化定义数组
数据类型[ ] 数组名 = new 数据类型[ ]{元素1,元素2...};
int[] number2 = new int[]{0,1,2};
int[] number2;
number2 = new int[]{0,1,2};
3、静态初始化简化定义数组
数据类型[ ] 数组名 = {元素1,元素2...}; 或 数据类型 数组名[ ] ={元素1,元素2...};
int[] number3 = {0,1,2};
int number3[] = {0,1,2};
4、数组相关操作
(1)数组变量名中存储的是数组在内存中的地址
字符数组直接输出数组名:将数组以字符串输出 在字符数组名前面加字符:输出的是地址
int[] number = {1,2,3};
System.out.println(number);
char[] chars = {'a','b','c'};
System.out.println(chars);
System.out.println(""+chars);
输出结果:
[I@776ec8df
abc
[C@404b9385
(2)访问数组长度:数组名.length
System.out.println(number.length);
(3)引用数组:数组名[ i ]
number[0]=0;
5、二维数组
二维数组的一维数组长度可以不同
int[][] number1 = new int[2][2];
int[][] number1;
number1 = new int[2][2];
int number2[][] = new int[][]{{1,1},{1,1}};
int number2[][];
number2 = new int[][]{{1,1},{1,1}};
int[] number3[] = {{1,1},{1,1}};
int[][] number= new int[2][];
number[0] = new int[2];
number[1] = new int[]{1,1};
System.out.println(number[1][1]);
System.out.println(number.length);
System.out.println(number[1].length);
int[] a,b[]; //a为一维数组,b为二维数组
六、分支结构
1、if-else语句
(1)if(条件表达式){ }
if(2 > 1){
System.out.println(1);
}
(2)if(条件表达式){ } else { }
if (2 < 1)
System.out.println(1); //当if子句只控制一行时,{ }可以省略不写
else{
System.out.println(2);
}
(3)if(条件表达式){ } else if(条件表达式){ } else { }
int score = 100;
if (score < 60)
System.out.println("未及格");
else if (score < 100)
System.out.println("及格"); //当else if子句只控制一行时,{ }可以省略不写
else
System.out.println("满分"); //当else子句只控制一行时,{ }可以省略不写
2、switch语句
switch(条件表达式){
case 数值:
语句
break;
default:
语句
}
int number = 3;
switch (number){
case 1:
System.out.println(1);
break;
case 2:
System.out.println(2);
break;
default:
System.out.println("大于2");
}
(1)条件表达式不支持long,float,double
(2)case后面的值不能重复,且只能是常量,不能是变量
(3)如果不加break语句,程序会向下执行
七、循环结构
1、for语句
for(初始化语句;循环条件;迭代语句) { 执行语句 }
for (int i = 1;i < 3;i++)
System.out.println(i); //当for语句只控制一行时,{ }可以省略不写
(1)初始化语句和迭代语句可以写在其他地方,但分号不能省略
int i = 1;
for( ;i < 10; ){
System.out.println(i);
i++;
}
(2)可以有多条初始化语句,要求类型一样,用逗号隔开,迭代语句也可以有多条语句,用逗号隔开
for(int i = 1,j = 10;i < 10; i++,j--){
System.out.println(i);
}
2、while语句
初始化语句 while(循环条件){ 执行语句 迭代语句 }
int i = 1;
while(i < 3)
System.out.println(i++); //当while语句只控制一行时,{ }可以省略不写
3、do while语句
初始化语句 do { 执行语句 迭代语句 } while(循环条件);
int n = 1;
do
System.out.println(n++); //当do语句只控制一行时,{ }可以省略不写
while(n < 3);
4、break语句
退出整个循环,若存在多层循环,则退出最近的循环
5、contiune语句
跳出这个循环的此次执行
八、方法
1、定义方法
public 返回值类型 方法名(形参列表) { 执行语句 return语句 }
(1)编写顺序无所谓,方法与方法之间是平级关系,不能嵌套定义,方法中不能再定义方法
(2)值传递:传递的是数据值,不是变量本身(数组传的是地址值)
(3)一个方法最多只有一个返回值,返回值类型可以为任意类型
(4)如果要求返回值,最后的执行语句必须为return语句,当返回值类型为void时,可以不写,也可以写 return ;
public class Test {
public static void main(String[] args) {
System.out.println(add(1,2));
}
public static int add(int a,int b){
return a + b;
}
}
2、方法重载
同一个类中,多个方法名相同,但是形参列表不同,称为重载方法(返回值类型和变量名无所谓)
public class Test {
public static void main(String[] args) {
System.out.println(add(1,2));
System.out.println(add(1,2,3));
}
public static int add(int a,int b){
return a + b;
}
public static int add(int a,int b,int c){
return a + b + c;
}
}
3、可变参数
public 返回值类型 方法名(数据类型... 形参名) { 执行语句 return语句 }
(1)一个形参列表中,只能出现一个可变参数,当作数组使用
(2)可变参数的实参可以是任意个,可以是数组
public class Test {
public static void main(String[] args) {
add(1,2,3);
int[] arr = {4,5,6};
add(arr);
}
public static void add(int... numbers){
System.out.println(numbers.length);
for (int i = 0; i < numbers.length ; i++) {
System.out.println(numbers[i]);
}
}
}
(3)可变参数可以和普通类型参数一起放在形参列表,需要放在最后
public class Test {
public static void main(String[] args) {
add(1.0,1,2,3);
}
public static void add(double n,int... numbers){
}
}
九、类
同一个java文件中可以定义多个class类,只能有一个是public修饰,类名必须为代码文件名
public class 类名{
1,成员变量
2,成员方法
3,构造器
4,代码块
5,内部类
}
1、创建对象
类名 对象名 = new 类名();
变量a1,a2中存储的是对象在内存中的地址
public class Test {
public static void main(String[] args) {
Apple a1 = new Apple();
Apple a2;
a2 = new Apple();
}
}
class Apple {
}
匿名对象,只调用一次
public class Test {
public static void main(String[] args) {
new Apple();
int n = new Apple().numbers;
new Apple().eat();
}
}
class Apple{
int numbers;
public void eat(){
}
}
2、构造器
修饰符 类名(形参列表){ }
定义在类中,可以用于初始化一个类的对象,并返回对象的地址,无返回值,也不能写void
(1)无参数构造器:默认存在,初始化对象时,成员变量的数据均采用默认值
class Apple {
public Apple(){
}
}
(2)有参数构造器:初始化对象时,同时可以接受参数为对象进行赋值
class Apple {
int n;
public Apple(int m){
n = m;
}
}
(3)可以定义多个不同的有参数构造器,即构造器重载
class Apple {
int n;
int m;
public Apple(int a){
n = a;
}
public Apple(int a, int b) {
n = a;
m = b;
}
}
(4)当有参构造器存在时,无参构造器就不默认存在了,如果需要,也要把无参构造器写出来
3、调用构造器
类名 对象名 = new 类名();
public class Test {
public static void main(String[] args) {
Apple a1 = new Apple();
Apple a2 = new Apple(1);
}
}
class Apple {
int n;
public Apple(){
}
public Apple(int m){
n=m;
}
}
4、this
(1)出现在方法,构造器中,代表当前对象的地址
public class Test {
public static void main(String[] args) {
Apple a1 = new Apple();
Apple a2 = new Apple(1);
a1.run();
a2.run();
}
}
class Apple {
int n;
public void run(){
System.out.println(this);
}
public Apple(){
System.out.println(this);
}
public Apple(int m){
n=m;
System.out.println(this);
}
}
(2)可以用于访问当前对象的成员
访问成员变量:this.变量名 访问成员方法:this.方法名(参数列表);
class Apple {
int n;
public Apple(int n){
this.n=n;
}
public void run(int m){
}
public void walk(){
this.run(1);
}
}
(3)可以用于访问当前对象的构造器
访问构造器 :this(参数列表); 只能在构造器中访问,且必须为第一条语句
class Apple {
int n;
public Apple(){
this(1);
}
public Apple(int n){
this.n=n;
}
}
十、封装
1、成员变量使用private修饰,只能本类访问
class Apple {
private int n;
}
2、提供setter和 getter方法进行取值和赋值
class Apple {
private int n;
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
}
3、必须提供无参构造器
十一、继承
子类 extends 父类 Son为子类(派生类),Father为父类(基类,超类)
public class Test {
public static void main(String[] args) {
}
}
class Father{
}
class Son extends Father{
}
1、继承的特点
(1)java中所有的类都是Object类的子类
(2)单继承,一个类只能直接继承一个父类,但可以多层继承
(3)子类可以继承父类的成员变量和方法,但是子类不可以继承父类的构造器
(4)子类可以直接访问父类的非私有的成员变量和成员方法,就近原则
2、方法重写
子类中出现了和父类中一模一样的方法声明,称子类的这个方法为重写的方法
(1)重写方法的名,形参列表必须与被重写方法的名,形参列表一致
(2)子类重写父类方法时,访问权限必须大于或等于父类
(3)私有的方法不能重写,静态的方法不能重写
(4)子类方法的返回类型要么和父类方法的返回类型一样,要么是父类返回类型的子类
public class Test {
public static void main(String[] args) {
Son t = new Son();
t.run();
}
}
class Father {
public void run(){
System.out.println(1);
}
}
class Son extends Father{
public void run(){
super.run();
System.out.println(2);
}
}
3、super
(1)可以用于访问父类的成员,就近原则,如果父类没有,就找父类的父类
super.父类的成员变量名 super.父类的成员方法名(参数列表);
public class Test {
public static void main(String[] args) {
Son t = new Son();
t.run();
}
}
class Father {
int a = 3;
public void out(){
System.out.print(5);
}
}
class Son extends Father{
int a = 2;
public void out(){
System.out.print(4);
}
public void run(){
int a = 1;
System.out.print(a);
System.out.print(this.a);
System.out.print(super.a);
out();
super.out();
}
}
输出结果: 12345
(2)可以用于访问父类的构造器
super语句必须放在构造器的第一行,需要父类的哪个构造器就用super语句来调用
子类构造器第一行语句默认都是 super(); 写不写都存在,默认先访问父类构造器中的无参构造器
public class Test {
public static void main(String[] args) {
Son s = new Son();
}
}
class Father {
public Father(){
System.out.println("父类的无参构造器被调用");
}
}
class Son extends Father {
public Son(){
super();
System.out.println("子类的无参构造器被调用");
}
}
输出结果:
父类的无参构造器被调用
子类的无参构造器被调用
如果父类中没有无参构造器,则必须在子类的构造器的第一行语句中使用 super(参数); 语句去指定访问父类的一个构造器来初始化继承自父类的数据
public class Test {
public static void main(String[] args) {
Son s = new Son();
}
}
class Father {
int n;
public Father(int n){
this.n=n;
System.out.println("父类的有参构造器被调用");
}
}
class Son extends Father {
public Son(){
super(1);
System.out.println("子类的无参构造器被调用");
}
}
输出结果:
父类的有参构造器被调用
子类的无参构造器被调用
4、this和super
(1)this:代表本类的引用(从本类开始向上查找,就近原则)
访问本类成员变量:this.成员变量;
访问本类成员方法:this.成员方法();
访问本类构造器:this(参数) ;
(2)super:代表父类的引用(从父类开始向上查找,就近原则)
访问父类成员变量:super.成员变量;
访问父类成员方法:super.成员方法();
访问父类构造器:super(参数) ;
(3)this(); 和 super(); 都只能放在构造器的第一行,所以二者不能共存在同一个构造器中
(4)子类通过this(); 调用本类其他构造器,本类其他构造器会通过super(); 调用父类的构造器
十二、多态
1、方法的多态
方法重载和重写都是多态的体现
2、对象的多态
(1)一个对象的编译类型和运行类型可以不一致
(2)编译类型看定义时 = 号的左边,运行类型看 = 号的右边
(3)编译类型在定义对象时就确定了不能改变,运行类型是可以改变的
引用名.getClass() 可查看运行类型
public class Test {
public static void main(String[] args) {
Animal one = new Cat();
System.out.println(one.getClass());
one = new Dog();
System.out.println(one.getClass());
}
}
class Animal {
}
class Dog extends Animal {
}
class Cat extends Animal{
}
(4) 多态的向上转型:
父类的引用指向了子类的对象,可以调用父类中所有成员,不可以调用子类中特有成员
父类类型 引用名 = new 子类类型(); 编译类型是父类类型,运行类型是子类类型
public class Test {
public static void main(String[] args) {
Animal one = new Cat();
one.a();
one.b();
}
}
class Animal {
public void a(){
}
public void b(){
}
}
class Cat extends Animal {
public void a(){
}
public void c(){
}
}
(5)多态的向下转型:只能强转父类的引用,不能强转父类的对象,要求父类的引用必须指向的是当前目标类型的对象,可以调用子类类型所有的成员
子类类型 引用名 = (子类类型)父类引用; 编译类型和运行类型都是子类类型
public class Test {
public static void main(String[] args) {
Animal one = new Cat();
Cat c = (Cat) one;
c.a();
c.b();
c.c();
}
}
class Animal {
public void a(){
}
public void b(){
}
}
class Cat extends Animal {
public void a(){
}
public void c(){
}
}
(6)属性看编译类型
public class Test {
public static void main(String[] args) {
Animal one = new Cat();
System.out.println(one.numbers);
Cat two = new Cat();
System.out.println(two.numbers);
}
}
class Animal {
int numbers = 1;
}
class Cat extends Animal {
int numbers = 2;
}
输出结果:
1
2
(7)比较操作符:instanceof,判断对象的运行类型是否为某个类型或者某个类型的子类型
public class Test {
public static void main(String[] args) {
Animal one = new Cat();
System.out.println(one instanceof Cat);
System.out.println(one instanceof Animal);
}
}
class Animal {
}
class Cat extends Animal {
}
输出结果:
true
true
(8)动态绑定机制:当调用对象方法时,该方法会和该对象的运行类型/内存地址绑定
public class Test {
public static void main(String[] args) {
Animal one = new Cat();
System.out.println(one.b());
System.out.println(one.c());
}
}
class Animal {
int i = 10;
public int a(){
return i;
}
public int b(){
return a()+10;
}
public int c(){
return i+10;
}
}
class Cat extends Animal {
int i = 20;
public int a(){
return i;
}
public int b(){
return i+20;
}
public int c(){
return i+10;
}
}
输出结果:
40
30
public class Test {
public static void main(String[] args) {
Animal one = new Cat();
System.out.println(one.b());
System.out.println(one.c());
}
}
class Animal {
int i = 10;
public int a(){
return i;
}
public int b(){
return a()+10;
}
public int c(){
return i+10;
}
}
class Cat extends Animal {
int i = 20;
public int a(){
return i;
}
public int c(){
return i+10;
}
}
输出结果:
30
30
public class Test {
public static void main(String[] args) {
Animal one = new Cat();
System.out.println(one.b());
System.out.println(one.c());
}
}
class Animal {
int i = 10;
public int a(){
return i;
}
public int b(){
return a()+10;
}
public int c(){
return i+10;
}
}
class Cat extends Animal {
int i = 20;
public int a(){
return i;
}
}
输出结果:
30
20
3、多态的应用
(1)多态参数:方法定义的形参类型为父类类型,实参类型为子类类型
public class Test {
public static void main(String[] args) {
run(new Cat());
}
public static void run(Animal animal){
animal.run();
}
}
class Animal {
public void run(){
System.out.println("我是动物");
}
}
class Cat extends Animal {
@Override
public void run() {
System.out.println("我是猫");
}
}
(2)多态数组:数组的定义类型为父类类型,保存的元素为子类类型
public class Test {
public static void main(String[] args) {
Animal[] animals1;
animals1 = new Animal[2];
Animal[] animals2 = new Animal[2];
animals2[0] = new Cat();
animals2[1] = new Cat();
}
}