Hello World
public class Hello{ public static void main(String[] args){ System.out.print("Hello,World"); } }
可能遇到的情况:
public class Hello { public static void main(String[] args) { // 单行注释 // 输出一个Hello,World! /* 我是多行注释 */ /** * 我是文档注释 */ System.out.println("com.xie.base.Hello,World!"); } }
关键字
Java所有的组成部分都需要名字,类名,变量名以及方法名都被称为标识符
public class Demo2 { public static void main(String[] args) { // 八大基本数据类型 // 整数 int num1 = 10; // 最常用 byte num2 = 20; short num3 = 30; long num4 = 40L; // Long类型要在数字后面加个L // 小数 浮点数 float num5 = 50.1F; // float类型要在数字后面加个F double num6 = 3.1415926; // 字符 char name = '国'; // 布尔值 是非 boolean flag = true; } }
拓展
public class Demo3 { public static void main(String[] args) { // 整数拓展:进制 二进制:0b 十进制 八进制:0 十六进制:0x int i1 = 0b10; // 二进制:0b int i2 = 10; int i3 = 010; // 八进制:0 int i4 = 0x10; // 十六进制:0x System.out.println(i1); System.out.println(i2); System.out.println(i3); System.out.println(i4); System.out.println("=============="); // 浮点数拓展 // 银行的业务一般不适用浮点数表述,有四舍五入等原因,而是使用BigDecimal:数学工具类 float f = 0.1f; double d = 1.0/10; System.out.println(f == d); // 理论显示应该是true,但是显示了false float f1 = 2313132313f; double d1 = f1 + 1 ; System.out.println(f1 == d1); // 理论显示应该是false,应该是true System.out.println("=============="); // 字符拓展 所有的字符本质还是数字 和编码有关 Unicode char c1 = 'A'; char c2 = '中'; char c3 = '\u0061'; System.out.println(c1); System.out.println((int)c1); // 强制类型转换 System.out.println(c2); System.out.println((int)c2); // 强制类型转换 System.out.println(c3); } } # 结果 2 10 8 16 ============== false true ============== A 65 中 20013 a
由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换
低---------------------------------------------------------->高
byte,short,char -> int -> long -> float -> double (小数的优先级一定大于整数)
运算中,不同类型的数据先转换为同一类型,然后进行运算
强制类型转换
自动类型转换
public class Demo4 { public static void main(String[] args) { // 强制转换 强制转换:高->低 自动转换:低->高 int i = 128; byte b = (byte)i; // 内存溢出 double b1 = i; System.out.println(i); System.out.println(b); System.out.println(b1); /* 注意点: 1. 不能对boolean类型转换 2. 不能把对象类型转换为不相干的类型 3. 在把高容量转换到低容量的时候,需要进行强制类型转换。低容量转高容量时自动转换 4. 转换的时候可能存在内存溢出,或者精度的问题 */ System.out.println("==========================="); double d1 = 23.7; float f1 = -45.87f; System.out.println((int)d1); System.out.println((int)f1); System.out.println("==========================="); char c = 'a'; int d2 = c+1; System.out.println(d2); System.out.println((char)d2); } } # 结果 128 -128 128.0 =========================== 23 -45 =========================== 98 b
注意细节
public class Demo5 { public static void main(String[] args) { // 操作比较大的数的时候,注意内存溢出问题 // jdk7新特性,数字之间可以用下划线分隔 int money = 10_0000_0000; int years = 20; int total1 = money*years; // 计算的时候内存溢出了 long total2 = money*years; // 在转换之前已经出问题了 long total3 = money*(long)years; // 正确的方式,先把一个转换为long System.out.println(total1); System.out.println(total2); System.out.println(total3); } } # 结果 -1474836480 -1474836480 20000000000
type varName [=value];
// 数据类型 变量名 = 值;
public class Demo6 { // 类变量 static 从属于类 static double salary = 2500; // 实例变量:从属于对象,如果不进行初始化,数字类型的默认值为0 0.0 // 布尔类型的默认值为false // 除了基本类型,其余类型的默认值都为null String name; int age; public static void main(String[] args) { // 局部变量:必须声明和初始化 int i = 10; System.out.println(i); System.out.println("==================="); Demo6 demo6 = new Demo6(); // 需要先new System.out.println(demo6.age); System.out.println(demo6.name); System.out.println("==================="); System.out.println(salary); // 不需要new } } # 结果 10 =================== 0 null =================== 2500.0
变量的命名规范
public class Demo7 { // 修饰符,没有先后顺序 static final double PI = 3.14; // 以下写法也可 final static double PI1 = 3.14; public static void main(String[] args) { System.out.println(PI); System.out.println(PI1); } } # 结果 3.14 3.14
Java语言支持如下运算符:
public class Demo1 { public static void main(String[] args) { // 二元运算符 int a = 10; int b = 20; System.out.println(a+b); System.out.println(a-b); System.out.println(a*b); System.out.println(a/(double)b); } } # 结果 30 -10 200 0.5
public class Demo2 { public static void main(String[] args) { long a = 15874594213566L; int b = 123; short c = 10; byte d = 8; System.out.println(a+b+c+d); // 有long类型输出结果就为long类型 System.out.println(b+c+d); // int类型 System.out.println(c+d); // int类型 } } 结果 15874594213707 141 18
public class Demo3 { public static void main(String[] args) { int a = 10; int b = 20; int c = 21; System.out.println(a>b); System.out.println(a<b); System.out.println(a==b); System.out.println(a!=b); // 取余,模运算 System.out.println(c%a); } } 结果 false true false true 1
public class Demo4 { public static void main(String[] args) { // ++ 自增 -- 自减 一元运算符 int a = 3; System.out.println("a="+a); int b = a++; // 先执行b=a,然后a自增 System.out.println("a="+a); int c = ++a; // 先自增,然后执行c=a System.out.println("a="+a); System.out.println("b="+b); System.out.println("c="+c); // 扩展 幂运算 2^3=8 很多运算,我们会使用工具类来进行运算 double pow = Math.pow(2, 3); System.out.println(pow); } } 结果 a=3 a=4 a=5 b=3 c=5 8.0
public class Demo5 { public static void main(String[] args) { // 逻辑运算 // 与(and) 或(or) 非(取反) boolean a = true; boolean b = false; System.out.println(b&&a); System.out.println(b||a); System.out.println(!(b&&a)); System.out.println("=================="); // 短路运算 int c = 5; boolean d = (c<4)&&(c++<4); System.out.println(d); System.out.println(c); // 因为判断c<4已经错了,所以没有执行c++,导致c依然等于5 boolean e = (c++>4)&&(c>4); System.out.println(e); System.out.println(c); // 这里执行了c++,c变为了6 } } 结果 false true true ================== false 5 true 6
public class Demo6 { public static void main(String[] args) { // 位运算 /* A = 0011 1100 B = 0000 1101 ------------------------ A&B = 0000 1100 //两个位都为1的时候才为1,其余都为0 A|B = 0011 1101 //两个位都为0的时候才为0,其余都为1 A^B = 0011 0001 // 两个位相同则为0,不相同则为1 ~B = 1111 0010 // 和对应为完全相反 计算 2*8 = 16 => 2*2*2*2 << 相当于 *2 << 相当于 /2 0000 0000 0 0000 0001 1=2^0 0000 0010 2=2^1 0000 0100 4=2^2 0000 1000 8=2^3 0001 0000 16=2^4 */ System.out.println(2<<3); } } 结果 16
public class Demo7 { public static void main(String[] args) { int a = 10; int b = 20; a+=b; System.out.println(a); System.out.println("============="); // 字符串连接符 System.out.println(""+a+b); System.out.println(a+b+""); } } 结果 30 ============= 3020 50
public class Demo8 { public static void main(String[] args) { // x ? y : z // 如果x==true,则结果为y,否则结果为z int score1 = 50; int score2 = 80; String type1 = score1 < 60 ? "不及格" : "及格"; String type2 = score2 < 60 ? "不及格" : "及格"; System.out.println(type1); System.out.println(type2); } } 结果 不及格 及格
为了更好地组织类,Java提供了包机制,用于区别类名的命名空间
包语句的语法格式为:
package pkg1[. pkg2[. pkg3]];
一般利用公司域名倒置作为包名
为了能够使用某一个包的成员,我们需要在ava程序中明确导入该包,使用“imoort”即可
import package1[. package2…].(classname|*);
package operater; /** * @author xie_xuchun * @create 2021-12-26 21:42 */ public class Demo9 { String name; /** * @author xie_xuchun * @param name * @return * @throws Exception */ public String abc(String name) throws Exception{ return name; } }
之前我们学的基本语法中并没有实现程序和人的交互,但是Java给我们提供了一个工具类,我们可以获取用户的输入。java.util.Scanner是Java5的新特性,我们可以通过Scanner类来获取用户的输入。
基本语法:
Scanner s = new Scanner(System.in);
通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据。
public class Demo1 { public static void main(String[] args) { Scanner scanner1 = new Scanner(System.in); Scanner scanner2 = new Scanner(System.in); System.out.println("使用next方式接收:"); if(scanner1.hasNext()){ // if判断可用可不用 String str = scanner1.next(); System.out.println("输出内容为:"+ str); } System.out.println("使用nextLine方式接收:"); if(scanner2.hasNextLine()){ String str1 = scanner2.nextLine(); System.out.println("输出内容为:"+ str1); } scanner1.close(); // 关于IO流的方法要关闭,不然会占用内存,注意在最后关闭 scanner2.close(); } } 结果 使用next方式接收: hello world 输出内容为:hello 使用nextLine方式接收: hello world 输出内容为:hello world
public class Demo2 { public static void main(String[] args) { // 输入多个数字,计算和并求出平均值,不是数字的时候自动退出 Scanner scanner = new Scanner(System.in); double sum = 0; int m = 0; System.out.println("请输入数据:"); while(scanner.hasNextDouble()){ double x = scanner.nextDouble(); m++ ; sum = sum + x; System.out.println("你输入了第"+m+"个数据,当前结果sum="+sum); } System.out.println(m+"个数的和为:"+sum); System.out.println(m+"个数的平均值为:"+(sum/m)); scanner.close(); } } 结果 请输入数据: 10 你输入了第1个数据,当前结果sum=10.0 20 你输入了第2个数据,当前结果sum=30.0 30 你输入了第3个数据,当前结果sum=60.0 dfgh 3个数的和为:60.0 3个数的平均值为:20.0
JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。
顺序结构是最简单的算法结构
语句与语句之间,框与框之间是按从上到下的顺序执行的,它是由若干个依次执行的步骤组成的,它是任何一个算法都离不开的基本算法结构。
if单选择结构
我们很多时候需要去判断一个东西是否可行,然后才去执行,这样一个过程中用if语句来表示
语法:
if(布尔表达式){
// 如果为true将执行的语句
}
public class Demo1 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入:"); String str = scanner.nextLine(); if(str.equals("hello")){ System.out.println("你输入了:"+str); } System.out.println("End"); scanner.close(); } } 结果 请输入: hello 你输入了:hello End
if双选择结构
语法
if(布尔表达式){
// 执行为true时的代码
}else{
// 执行为false时的代码
}
public class Demo2 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入考试成绩:"); Double score = scanner.nextDouble(); if(score>=60){ System.out.println("考试及格!"); }else{ System.out.println("考试不及格!"); } scanner.close(); } } 结果 请输入考试成绩: 90 考试及格!
if多选择结构
语法:
if(布尔表达式1){
// 如果布尔表达式1成立时执行
}else if(布尔表达式2){
// 如果布尔表达式2成立时执行
}else if(布尔表达式3){
// 如果布尔表达式3成立时执行
}else{
// 以上布尔表达式都不成立时执行
}
public class Demo3 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入考试成绩:"); Double score = scanner.nextDouble(); if(score==100){ System.out.println("满分!"); }else if(score >= 90 && score <100){ System.out.println("A级"); }else if(score >= 80 && score <90){ System.out.println("B级"); }else if(score >= 70 && score <80){ System.out.println("C级"); }else if(score >= 60 && score <70){ System.out.println("D级"); }else if(score >= 0 && score < 60){ System.out.println("不及格"); }else{ System.out.println("不合法"); } scanner.close(); } } 结果 请输入考试成绩: 85 B级
嵌套的if结构
语法
if(布尔表达式1){
// 当布尔表达式1成立时执行
if(布尔表达式2){
// 当布尔表达式2成立时执行
}
}
switch多选结构
多选结构还有一个实现方式就是switch case语句。
switch case语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支
语法
switch语句中的变量类型可以是:
public class Demo4 { public static void main(String[] args) { String name = "江南"; switch (name){ case "哈哈": System.out.println("哈哈"); break; case "江南": System.out.println("江南"); break; default: System.out.println("啥也不是"); break; } } } 结果 江南
while循环
while是最基本的循环,他的结构为:
while(布尔表达式){
// 循环结构
}
只要布尔表达式为true,循环就会一直执行下去
我们大多数情况是会让循环停止下来,我们需要一个让表达式失效的方式来结束循环
少部分情况需要循环一直执行,不如服务器的请求响应监听等
循环条件一直未true就会造成死循环,我们正常的业务编程应尽量避免死循环,会影响程序性能或者造成卡死奔溃
public class Demo5 { public static void main(String[] args) { int sum = 0; int i = 0; while(i<=100){ sum = sum + i; i++; } System.out.println("0-100的和为:"+sum); } } 结果 0-100的和为:5050
do…while循环
对于while而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次
do…while循环和while循环相似,不同的是,do…while循环至少执行一次
do{
// 代码语句
}while(布尔表达式);
while和do…while的区别
public class Demo6 { public static void main(String[] args) { int i = 0; while (i<0){ System.out.println(i); } System.out.println("==============="); do{ System.out.println(i); }while(i<0); } } 结果 =============== 0
for循环
for循环语句是支持迭代的一种通用结构,是最有效,最灵活的循环结构
for循环执行的次数是在执行前就确定的,语法格式如下
for(初始化:布尔表达式;更新){
// 代码结构
}
public class Demo7 { public static void main(String[] args) { // 计算0-100之间奇数和偶数的和 int oddSum = 0; int evenSum = 0; for (int i = 0; i <= 100; i++) { if(i%2!=0){ // 取模不等于0位奇数 oddSum+=i; }else{ evenSum+=i; } } System.out.println("奇数的和:"+oddSum); System.out.println("偶数的和:"+evenSum); } } 结果 奇数的和:2500 偶数的和:2550
public class Demo8 { public static void main(String[] args) { // 输出1-50之间能被5整除的数,每3个换一行 for (int i = 1; i <= 50; i++) { if(i%5==0){ System.out.print(i+"\t"); } if(i%(5*3)==0){ System.out.print("\n"); } } } } 结果 5 10 15 20 25 30 35 40 45 50
public class Demo9 { public static void main(String[] args) { for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { System.out.print(j+"*"+i+"="+i*j+"\t"); } System.out.println(); } } } 结果 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
public class Demo10 { public static void main(String[] args) { int[] numbers = {10,20,30,40,50}; for (int i = 0; i < 5; i++) { System.out.print(numbers[i]+"\t"); } System.out.println(); System.out.println("================"); for (int x:numbers){ System.out.print(x+"\t"); } } } 结果 10 20 30 40 50 ================ 10 20 30 40 50
public class Demo11 { public static void main(String[] args) { // 打印一个三角形 for (int i = 1; i <= 5; i++) { for (int j = 5; j >= i; j--) { System.out.print(" "); } for (int j = 1; j <= i; j++) { System.out.print("*"); } for (int j = 1; j < i; j++) { System.out.print("*"); } System.out.println(); } } } 结果 * *** ***** ******* *********
何谓方法?
public class Demo1 { public static void main(String[] args) { int add = add(1, 2); System.out.println(add); } public static int add(int a,int b){ return a+b; } } 结果 3
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:
方法包含一个方法头和一个方法体,下面是一个方法的所有部分:
修饰符:可选,告诉编译器如何调用该方法。定义该方法的访问类型
返回值类型:方法可能会返回值。returnValueType是方法返回值得数据类型。有些方法执行所需的操作,但没有返回值,关键字为void。
方法名:参数是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 形式参数){ 方法体 返回值 }
调用方法:对象名.方法名(实参列表)
Java支持两种调用方法的方式,根据方法是否返回值来选择
当方法返回一个值得时候,方法调用通常被当做一个值,例如:
如果方法返回值是void,方法调用一定是一条语句。
Java是值传递
public class Demo2 { public static void main(String[] args) { int large = large(20, 20); System.out.println(large); } public static int large(int num1,int num2){ int result = 0; if(num1==num2){ return result; } if(num1 > num2){ result = num1; }else{ result = num2; } return result; } } 结果 0
public class Demo2 { public static void main(String[] args) { double large = large(30.0, 20); System.out.println(large); } public static int large(int num1,int num2){ int result = 0; if(num1==num2){ return result; } if(num1 > num2){ result = num1; }else{ result = num2; } return result; } public static double large(double num1,double num2){ double result = 0; if(num1==num2){ return result; } if(num1 > num2){ result = num1; }else{ result = num2; } return result; } } 结果 30.0
public class Demo3 { public static void main(String[] args) { for (int i = 0; i <args.length ; i++) { System.out.println("args的第"+i+"个参数为:"+args[i]); } } }
public class Demo4 { public static void main(String[] args) { printMax(34,35,33,31.0,38); printMax(new double[]{11,25.6,33.0,45}); } public static void printMax(double... numbers){ if (numbers.length == 0){ System.out.println("No argument passed"); return; } double result = numbers[0]; for (int i = 0; i < numbers.length; i++) { if (numbers[i] > result){ result = numbers[i]; } } System.out.println("数组中最大的数为:"+result); } } 结果 数组中最大的数为:38.0 数组中最大的数为:45.0
public class Demo5 { public static void main(String[] args) { // 递归计算5! int f = f(5); System.out.println(f); } public static int f(int n){ if (n == 1){ return 1; } return n*f(n-1); } } 结果 120
首先必须声明数组变量,才能在程序中使用数组,下面是声明数组变量的语法:
dataType[] arrayRefvar; // 首选的方法
或
dataType arrayRefvar[]; // 效果相同,但不是首选方法
Java语言使用new操作符来创建数组,语法如下:
数组的元素是通过索引访问的,数组索引从0开始
获取数组长度:arrays.length
public class Demo1 { public static void main(String[] args) { int[] nums = new int[10]; // 声明并创建数组 for (int i = 0; i < nums.length; i++) { // 给数组赋值 nums[i]=i+1; System.out.print(nums[i]+"\t"); } int sum = 0; for (int i = 0; i < nums.length; i++) { // 数组元素求和 sum = sum + nums[i]; } System.out.println(); System.out.println(sum); } } 结果 1 2 3 4 5 6 7 8 9 10 55
public class Demo2 { public static void main(String[] args) { // 静态初始化 int[] a = {1,2,3}; Man[] mans = {new Man(),new Man()}; System.out.println(a[1]); // 动态初始化 int[] b = new int[5]; b[0] = 1; b[1] = 2; System.out.println(b[1]); // 数组的默认初始化,默认值有0 0.0 null String[] c = new String[8]; System.out.println(c[5]); } } 结果 2 2 null
普通for循环
for-each循环
数组做方法入参
数组做返回值
public class Demo3 { public static void main(String[] args) { int[] nums = {-1,1,2,3,4,-5}; // 打印出数组的所有元素 for (int i = 0; i < nums.length; i++) { System.out.print(nums[i]+"\t"); } System.out.println(); System.out.println("==========================="); // 取出数组中的最大值 int max = nums[0]; for (int i = 0; i < nums.length; i++) { if (nums[i] > max){ max = nums[i]; } } System.out.println(max); } } 结果 -1 1 2 3 4 -5 =========================== 4
public class Demo4 { public static void main(String[] args) { int[] nums = {-1,1,2,3,4,-5}; // 打印出数组的所有元素 for (int array: nums) { System.out.print(array+"\t"); } } } 结果 -1 1 2 3 4 -5
public class Demo5 { public static void main(String[] args) { int[] nums = {-1,1,2,3,4,-5}; int[] reverse = reverse(nums); show(reverse); } public static int[] reverse(int[] arrays){ int[] result = new int[arrays.length]; for (int i = 0,j=arrays.length-1; i < arrays.length; i++,j--) { result[j] = arrays[i]; } return result; } public static void show(int[] reverse){ for (int array: reverse) { System.out.print(array+"\t"); } } } 结果 -5 4 3 2 1 -1
public class Demo6 { public static void main(String[] args) { int[][] array = {{1,2},{3,4},{5,6},{7,8}}; System.out.println(array.length); System.out.println(array[3][1]); System.out.println(array[1].length); System.out.println("========================"); for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[i].length; j++) { System.out.print(array[i][j]+"\t"); } } } } 结果 4 8 2 ======================== 1 2 3 4 5 6 7 8
public class Demo7 { public static void main(String[] args) { int[] a = {12,15,486,14,579,5416,265}; int[] b = {12,15,486,14,579,5416,265}; System.out.println(Arrays.toString(a)); Arrays.sort(a); System.out.println(Arrays.toString(a)); Arrays.fill(a,0,3,5); System.out.println(Arrays.toString(a)); System.out.println(Arrays.equals(a,b)); System.out.println(Arrays.binarySearch(a,0,a.length,5416)); } } 结果 [12, 15, 486, 14, 579, 5416, 265] [12, 14, 15, 265, 486, 579, 5416] [5, 5, 5, 265, 486, 579, 5416] false 6
public class Demo8 { public static void main(String[] args) { double[] a = {1,58,45.6,32,15.5,54,89.0,32,54}; double[] sort = sort(a); System.out.println(Arrays.toString(sort)); } public static double[] sort(double[] arrays){ double temp = 0; for (int i = 0; i < arrays.length-1; i++) { boolean flag = false; for (int j = 0; j < arrays.length-1; j++) { if (arrays[j+1] < arrays[j]){ temp = arrays[j+1]; arrays[j+1] = arrays[j]; arrays[j] = temp; flag = true; } } if (flag == false){ break; } } return arrays; } } 结果 [1.0, 15.5, 32.0, 32.0, 45.6, 54.0, 54.0, 58.0, 89.0]
// 定义一个学生类 public class Student { String name; int age; } public class Man { public static void main(String[] args) { // 实例化学生类 Student student1 = new Student(); Student student2 = new Student(); student1.name="xiaohong"; student1.age = 10; student2.name = "xiaoming"; student2.age = 10; System.out.println(student1.name); System.out.println(student1.age); System.out.println(student2.name); System.out.println(student2.age); } } 结果 xiaohong 10 xiaoming 10
结论:类是抽象的,对象是具体的。通过new关键字将抽象的类实例化为一个个的对象。
通过new关键字实例化对象实际上是调用抽象类中的构造器(构造器实际就是方法),分为有参构造和无参构造。在什么都不写的情况下,默认会有一个无参构造,当写了有参构造之后,如果想使用无参构造,无参构造必须显式写出。
public class Person { String name; int age; // 写了有参构造,无参构造必须显式写出 public Person(){} public Person(String name,int age){ this.name = name; this.age = age; } public Person(String name){ this.name = name; } } public class Application { public static void main(String[] args) { // new的过程实际是调用类中的构造器 Person person = new Person("xiaoming",10); System.out.println(person.name); } } 结果: xiaoming
public class Pet { public String name; public int age; public void shout(String str){ System.out.println(str + "叫了一声..."); } } public class Animal { public static void main(String[] args) { Pet dog = new Pet(); dog.name = "旺财"; dog.age = 3; dog.shout(dog.name); Pet cat = new Pet(); cat.name = "兴旺"; cat.age = 2; cat.shout(cat.name); } } 结果 旺财叫了一声... 兴旺叫了一声...
栈里面存放方法和对象的引用。堆中存放的是具体的实例对象,方法区也属于堆,在类加载的时候已经加载,所以静态方法可以直接调用。
类与对象
方法
对象的应用
属性
对象的创建和使用
类
public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { if(age > 120 || age < 0){ this.age = 3; }else{ this.age = age; } } } public class Application { public static void main(String[] args) { Student s1 = new Student(); s1.setName("xxc"); s1.setAge(150); System.out.println(s1.getName()); System.out.println(s1.getAge()); } } 结果 xxc 3
注意:封装是属性的封装。
public class Person { private String name; private int age; public void sleep(int age , String name){ System.out.println(name+"今年"+age+"岁,现在睡着了..."); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } // 子类继承父类,就会拥有父类的所有方法 public class Student extends Person { } public class Application { public static void main(String[] args) { Student s1 = new Student(); s1.setName("小王"); s1.setAge(3); String name = s1.getName(); int age = s1.getAge(); s1.sleep(age,name); } } 结果 小王今年3岁,现在睡着了...
public class Person { protected String name = "xxc"; } public class Student extends Person{ private String name = "jiangnan"; public void test(String name){ System.out.println(name); System.out.println(this.name); System.out.println(super.name); } } public class Application { public static void main(String[] args) { Student student = new Student(); student.test("旺仔"); } } 结果 旺仔 jiangnan xxc
super注意点:
super vs this:
public class Person { public void show(){ System.out.println("Person=>show"); } } public class Student extends Person{ public void show(){ System.out.println("Student=>show"); } } public class Application { public static void main(String[] args) { // 父类引用指向子类对象 Person student = new Student(); student.show(); } } 结果 Student=>show
重写:
需要有继承关系,子类重写父类的方法
重写:子类和父类的方法必须一致,只是方法体不同
为什么要重写:
即同一方法可以根据发送对象的不同而采取多种不同的行为方式
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
多态存在的条件
注意:多态是方法的多态,和属性无关
instanceof
public class Person { public void show(){ System.out.println("这里是Person"); } } public class Student extends Person{ public void show(){ System.out.println("这里是Student"); } public void eat(){ System.out.println("Student==>eat"); } } public class Application { public static void main(String[] args) { Student student1 = new Student(); Person student2 = new Student(); student1.show(); // 显示Student本身的方法结果 student2.show(); // 显示重写后的方法结果 student1.eat(); // 显示Student本身的方法结果 ((Student) student2).eat(); // 无法重写,只能先强制类型转换 } } 结果 这里是Student 这里是Student Student==>eat Student==>eat
instanceof
public class Person { public void show(){ System.out.println("这里是Person"); } } public class Student extends Person { public void show(){ System.out.println("这里是Student"); } public void eat(){ System.out.println("Student==>eat"); } } public class Teacher extends Person{ } public class Application { public static void main(String[] args) { Student student1 = new Student(); System.out.println(student1 instanceof Object); System.out.println(student1 instanceof Student); //System.out.println(student1 instanceof Teacher); // 编译报错,因为Student1和Teacher没有关系 System.out.println("=========================="); Object student = new Student(); System.out.println(student instanceof Object); System.out.println(student instanceof Teacher); // 编译不报错,因为Student和Teacher都继承与Object System.out.println(student instanceof Student); System.out.println("=========================="); Person student2 = new Student(); student2.show(); ((Student) student2).eat(); // Person本身没有eat();方法,调用的话需要强制类型转换 } } 结果 true true ========================== true false true ========================== 这里是Student Student==>eat
结论:引用类型的强制类型转换和基本类型的相似。低转高自动转,高转低需要强制类型转换。
static
public class Student { { // 可以用这种方法赋初始值 System.out.println("匿名代码块"); } static { System.out.println("静态代码块"); } public Student(){ System.out.println("构造方法"); } public static void main(String[] args) { Student student1 = new Student(); System.out.println("==========================="); Student student2 = new Student(); } } 结果 静态代码块 匿名代码块 构造方法 =========================== 匿名代码块 构造方法
结论:可以发现静态代码块最先执行,而且只执行一次。其他的方法在每次实例化对象的时候都会执行。可以利用匿名代码块给对象赋一些初始值,因为匿名代码块在构造方法之前执行
public abstract class Action { public abstract void run(); } public class Action1 extends Action{ @Override public void run() { System.out.println("子类必须实现父类中的出现方法"); } } public class Application { public static void main(String[] args) { // Action action = new Action(); 无法使用new关键字 Action1 action1 = new Action1(); action1.run(); } } 结果 子类必须实现父类中的出现方法
结论:父类为抽象类,那么子类必须实现父类中的抽象方法,除非子类也是抽象类。抽象类不能被new关键字进行实例化。
public interface UserService { // 只能定义方法,不能实现 void add(); void delete(); void update(); void query(); } public interface TimerService { void timer(); } public class UserServiceImpl implements UserService,TimerService{ // 多继承 @Override public void add() { // 实现具体的方法 System.out.println("我实现了add方法"); } @Override public void delete() { System.out.println("我实现了delete方法"); } @Override public void update() { System.out.println("我实现了update方法"); } @Override public void query() { System.out.println("我实现了query方法"); } @Override public void timer() { System.out.println("我实现了timer方法"); } } public class Application { public static void main(String[] args) { UserServiceImpl userService = new UserServiceImpl(); userService.add(); userService.delete(); userService.update(); userService.query(); userService.timer(); } } 结果 我实现了add方法 我实现了delete方法 我实现了update方法 我实现了query方法 我实现了Timer方法
// 成员内部类 public class Outer { private int age = 10; public void run(){ System.out.println("Outer=>run"); } class Inner{ public void show(){ System.out.println("Inner=>run"); } public void getAge(){ System.out.println("我是内部类,我可以操作外部类的属性和方法:"+age); } public void InnerRun(){ run(); } } } public class Application { public static void main(String[] args) { Outer outer = new Outer(); outer.run(); Outer.Inner inner = outer.new Inner(); inner.InnerRun(); // 通过内部类获取外部类的方法 inner.show(); inner.getAge(); } } 结果 Outer=>run Outer=>run Inner=>run 我是内部类,我可以操作外部类的属性和方法:10
静态内部类使用static修饰即可
// 局部内部类 public class Outer { public void method(){ System.out.println("Outer=>method"); class Inner{ public void in(){ System.out.println("我是局部内部类的方法"); } } Inner inner = new Inner(); inner.in(); } } public class Application { public static void main(String[] args) { Outer outer = new Outer(); outer.method(); } } 结果 Outer=>method 我是局部内部类的方法
结论:局部内部类只能在局部使用,不能再其他类中调用
// 匿名内部类 public class Outer { public void show(){ System.out.println("我是外部类的方法"); } } class Inner{ public void eat(){ System.out.println("我是内部类的方法"); } } public class Application { public static void main(String[] args) { Outer outer = new Outer(); // 我被实例化为了具体的outer对象 outer.show(); // 通过我的实例化对象去调用了我的方法 new Inner().eat(); // 我没有被实例化对象,而是直接调用了方法 } } 结果 我是外部类的方法 我是内部类的方法
public class OuterService { public static void main(String[] args) { new UserService(){ @Override public void eat() { System.out.println("我重写了eat方法"); } }.eat(); } } interface UserService{ void eat(); } 结果 我重写了eat方法
public class Test { public static void main(String[] args) { try { new Test().a(); }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(); } } 结果 Error finally
结论:
public class Test { public static void main(String[] args) { int a = 1; int b = 1; try { new Test().test(a,b); System.out.println(new Test().shout(a,b)); } catch (Exception e) { System.out.println("有异常,请处理"); }finally { System.out.println("finally"); } } public void test(int a,int b) { if (b == 0){ throw new ArithmeticException(); } } public int shout(int a,int b){ return a/b; } } 结果 1 finally
总结:throw在方法中手动抛出异常,throws在方法上主动抛出异常,一般在方法中没法处理异常的时候采用。
public class Test { public static void main(String[] args) { try { new Test().a(); }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(); } } 结果 Error finally
结论:
public class Test { public static void main(String[] args) { int a = 1; int b = 1; try { new Test().test(a,b); System.out.println(new Test().shout(a,b)); } catch (Exception e) { System.out.println("有异常,请处理"); }finally { System.out.println("finally"); } } public void test(int a,int b) { if (b == 0){ throw new ArithmeticException(); } } public int shout(int a,int b){ return a/b; } } 结果 1 finally
总结:throw在方法中手动抛出异常,throws在方法上主动抛出异常,一般在方法中没法处理异常的时候采用。