简介 Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点
Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等
参考资料 IDEA Mac快捷键
函数 简介
函数的概念
函数就是定义在类中的具有特定功能
的一段独立小程序
函数也成为方法
通俗的说:函数(方法)是一段可重复调用的代码段
函数分类
普通方法:静态(static)、类方法和实例(对象)方法
构造函数
其它说明:
传参
有参数,则必须传入参数
传参类型要一致
传参个数也要一致,没有则不需要传参
返回值
用关键字return
来返回
返回值 void 的方法默认是有一个 return 返回至调用处,一般不写
如果有返回值,return的值要与定义的返回值类型一致
可变参数
可变参数是 jdk1.5 的新特性
public static 返回值类型 方法名称(数据类型… 参数名称) 会把传入的数据类型组成一个数组
类方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package com.tester.ada.function;public class FunctionTester { public static void main (String[] args) { getDayInfo(1 ); System.out.println("调用返回值:" +getDayInfo(1 )); } private static String getDayInfo (int day) { switch (day) { case 1 : case 2 : case 3 : case 4 : case 5 : System.out.println("今天是工作日" ); break ; case 6 : case 7 : System.out.println("今天是周末" ); break ; default : System.out.println("非法的数值" ); } return "调用成功" ; } }
对象方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package com.tester.ada.function;public class FunctionTester2 { public static void main (String[] args) { FunctionTester2 tester = new FunctionTester2 (); int aInt = 3 ; double aDouble = 10 ; System.out.println(tester.sum(aInt,aDouble)); System.out.println(tester.sum(8 ,12.75 )); } private double sum (int aInt,double aDouble) { return aInt + aDouble; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package com.tester.ada.function;public class FunctionTester3 { public static void main (String[] args) { int [] ints = {1 , 2 , 3 , 4 }; FunctionTester3 functionTester3 = new FunctionTester3 (); System.out.println(functionTester3.plus(ints)); System.out.println(functionTester3.sum(ints)); functionTester3.say("h" ,"e" ,"ll" ,"o" ); } private int plus (int [] ints) { int sum = 0 ; for (int i = 0 ; i < ints.length; i++) { sum += ints[i]; } return sum; } private int sum (int [] ints) { int sum1 = 0 ; for (int aInt : ints ) { sum1 += aInt; } return sum1; } private void say (String... aStr) { String aString = null ; for (String aStr1 : aStr) { System.out.print(aStr1); } } }
面向对象 简介
Java 是面向对象的语言,在 Java 中,一切皆为对象
每一个人都是一个对象
属性:姓名、性别、年龄、身高、星座
行为:吃饭、睡觉、学习、打豆豆
类与对象
类:共性事务的抽象,是对某一具有共性事物的描述,是概念上的定义
对象:对象是共性事务的一个个体现,是这个类事务的一个个体或者说是类的一个实例(instance)
一个对象是数据和相关方法的集合,数据是对象的状态,方法是对象的行为
面向对象概念构成了 Java 的核心
面向对象具有封装
继承
多态
三大特性
解释:人、手机、水果、苹果是一个类,具体的某个人比如你 比如我是一个具体对象 你的手机 我的手机是一个具体的对象 水果是一个更大的类包含了苹果类可以当成它的父类
总结:① 类是抽象的、很泛的一个概念,对象是某一具体的的事物 ② 类是对象的模板,对象是类的实例
场景:小明 坐着 D553高铁 去拉萨
类:人类、火车类、地理位置类
对象:小明、D553高铁、拉萨
方法、行为:坐着、去
类的创建和实例化 创建类
1 2 3 4 5 6 7 8 9 10 修饰符 class 类名称{ 修饰符 数据类型 属性; .... public 返回值数据类型 方法名称(参数类型 参数名,参数类型 参数名2 ){ return 表达式; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package com.tester.ada.target;public class MemberTester { String phone; String pwd; String regName; String amount; public String register (String phone, String pwd, String regName) { if (11 == phone.length() && 6 == pwd.length() && 8 >= regName.length()) { return "注册成功" ; } else { return "用户信息错误" ; } } public String login (String phone, String pwd) { if (11 == phone.length() && 6 == pwd.length()) { return "Login success" ; } else { return "Login failed" ; } } }
对象实例化
语法声明
1 2 3 4 5 6 类名称 对象名称 = new 类名称(); 类名称 对象名称 = null ; 对象名称 = new 类名称();
访问属性:对象名称.属性名;
为属性赋值:对象名称.属性名 = 值;
访问方法:对象名称.方法名();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.tester.ada.target;public class MemberExampleTester { public static void main (String[] args) { MemberTester ada = new MemberTester (); ada.phone = "13555555555" ; ada.pwd = "123456" ; ada.regName = "阿达" ; System.out.println(ada.register(ada.phone, ada.pwd, ada.regName)); } }
构造函数 概念
构造函数
是用构造对象
的函数
示例:User user = new User();
构造方法必须与类名一致
使用 new 关键字进行调用
在每个类中都存在一个默认的无参构造方法,默认不显示
分类
构造函数分为两类:带参和无参的构造函数
1 2 3 public 类名称(参数类型 参数名,参数类型 参数名){ ... }
其它说明:
构造函数无返回值,返回的是一个具体的对象
参数类型为 8 大基本数据类型、引用类型
可以重写默认的构造函数(但是这种应该用处不大,一般都是自己重新定义一个带参数的构造函数)
写带参数的构造函数的目的是为了方便创建对象 初始化对象
如果显示的写了构造函数后,还想调用无参的构造函数
,就必须显示声明
一个无参构造函数
注意事项
调用构造函数语法
类名 对象名 = new 类名(); 无参构造函数(默认带有一个,如果写了有参的必须显示声明后才能使用,否则找不到)
类名 对象名 = new 类名(value1,value2); 有参的构造函数
其它注意事项
调用带参构造函数创建对象,可以按照我们的意愿来初始化对象的属性(方便我们初始化对象)
调用无参构造函数:对象属性值对应类型默认值
默认构造函数是自带的
(如果没有声明,则编码器会自动补齐)
如果定义了带参构造函数
,会覆盖
无参构造函数,此时如果需要调用无参构造函数,则必须显示
定义无参构造函数
创建
this
表示当前对象,也就调用的对象
如果构造函数中不用 this.phone = phone; 而是采用 phone = phone; 由于就近原
则两个 phone 都是使用的形参的这样就不起作用,除非把形参的变量名和属性名设置成不同的,不过一般不这样用,每次都要去起两个变量名,阅读性也不高
构造函数中的参数可以添加非属性的其它参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package com.tester.ada.target;public class MemberTester { String phone; String pwd; String regName; String amount; public MemberTester (String phone, String pwd, String regName, String amount) { this .phone = phone; this .pwd = pwd; this .regName = regName; this .amount = amount; } public MemberTester () { } public String register (String phone, String pwd, String regName) { if (11 == phone.length() && 6 == pwd.length() && 8 >= regName.length()) { return "注册成功" ; } else { return "用户信息错误" ; } } public String login (String phone, String pwd) { if (11 == phone.length() && 6 == pwd.length()) { return "Login success" ; } else { return "Login failed" ; } } }
调用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.tester.ada.target;public class MemberExampleTester { public static void main (String[] args) { MemberTester ada = new MemberTester (); ada.phone = "13555555555" ; ada.pwd = "123456" ; ada.regName = "阿达" ; System.out.println(ada.register(ada.phone, ada.pwd, ada.regName)); MemberTester link = new MemberTester ("13888888888" , "666666" , "link" , "8000" ); System.out.println(link.register(link.phone, link.pwd, link.regName)); } }
内存分配 分配过程
声明对象:Person per = null; 声明对象时会把 per 对象存在占内存中
实例化对象:per = new Person(); 会给 per 对象开辟一段队内存空间(给对象赋的属性值就会在这块堆内存中,此时还没给对象的属性进行赋值,那么这些属性值都是类型对应的缺省值 如 String–>null int–>0 )
关联:栈内存中的 per 对象会保存一个地址指向堆内存地址的引用 如 0x1354464548
存放分类
栈内存
基本类型变量(基本数据类型 四类八种)
对象引用,应用类型名称(比如上面的 per),即队堆的引用地址
堆内存
全局数据区(静态区)
全局代码区
字符串池(常量池)
jdk1.7 前在方法区,1.7 后再堆中间
共享的 String 对象
内存地址 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package com.tester.ada.target;public class MemoryTester { public static void main (String[] args) { String str1 = "hello" ; String str2 = "hello" ; String str3 = new String ("hello" ); String str4 = new String ("hello" ); System.out.println(str1 == str2); System.out.println(str2 == str3); System.out.println(str3 == str4); System.out.println("---------------重新分配地址---------------" ); str3 = str1; str4 = str2; System.out.println(str3 == str4); System.out.println("---------------此时 str3 和 str4 的内存没有人引用了会成为垃圾内存,会被 gc 回收---------------" ); } }
包装类 简介
数据类型分类:基本数据类型和引用数据类型
矛盾:基本数据类型不是类(类都是大写),因此 Java 为了调和矛盾引入了包装类
解决矛盾:8 个基本数据类型对应 8 个包装类
类型
基本数据类型
包装类
整型
byte
Byte
~
short
Short
~
int
Interger
~
long
Long
浮点型
float
Float
~
double
Double
字符型
char
Character
布尔型
boolean
Boolean
包装类:以类的形式来管理基本数据类型
如 Integer 使用类的形式表示整数
Integer i = new Integer(20);
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package com.tester.ada.packages;public class PackageClassTester { public static void main (String[] args) { System.out.println(Integer.MAX_VALUE); System.out.println(Integer.MIN_VALUE); Integer aInteger = new Integer (10 ); System.out.println(aInteger); Integer Integer = new Integer (20 ); Double aDouble = new Double (20.5 ); Integer Integer2 = 30 ; int aInt = Integer.intValue(); double adouble = aDouble.doubleValue(); System.out.println(aInt); System.out.println(adouble); int bInt = Integer; } }
包装类常用方法 xxxValue()
获得最大最小值
获得最大值:Integer.MAX_VALUE
获得最小值:Integer.MIN_VALUE
将字符串转换为基本数据类型
1 2 3 4 String str = "10086" ;int i = Integer.parseInt(str);double d = Double。parseDouble(str);String str2 = String.parseString(i);
转换 示例一 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package com.tester.ada.conversion;public class TypeConversionTester { public static void main (String[] args) { int i = 10 ; double doubleValue = 20 ; double d = i; int j = (int ) doubleValue; System.out.println("d的值为:" + d + ",j的值为:" + j); } }
示例二 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.tester.ada.conversion;public class MemberTester { InvestTester tom = new InvestTester (); BorrowerTester jack = new BorrowerTester (); MemberTester tom1 = tom; MemberTester jack1 = jack; MemberTester link = new MemberTester (); MemberTester ada = new MemberTester (); InvestTester link1 = (InvestTester) link; BorrowerTester ada1 = (BorrowerTester) ada; InvestTester tom3 = new InvestTester (); BorrowerTester tom4 = (BorrowerTester) tom3; }
1 2 3 4 5 6 7 8 9 10 11 package com.tester.ada.conversion;public class InvestTester extends MemberTester {}
1 2 3 4 5 6 7 8 9 10 11 package com.tester.ada.conversion;public class BorrowerTester extends MemberTester {}
Java 三大特性 封装 概念
封装是 Java 三大特性之一,把对象的内部细节
封闭起来,只提供操作对象属性的公共方法(把属性设置为 private,然后提供公共公开的 set get 方法)
封装是面向对象编程语言对客观世界的模拟
例如,电视机它的内部元件就是被封闭起来了,仅仅暴露电视机按钮供人们使用,这样就没有人能任意更改咱们的元件
Java 里面通过将属性设置成私有
的,对属性都使用暴露出来的公共接口去操作,这样数据才更安全,更好维护
目的
通过公开方法访问数据,可以从方法里加入逻辑控制,避免不合理的访问,可进行数据检查,保证数据完整性,防止不希望的交互和非法的访问便于后期修改,提高代码的可维护性
实现
属性私有化:隐藏对象的属性和实现细节,不允许外部直接访问(设置为 private,这样就不能通过 对象.属性名 调用)
提供公开的方法操作和访问属性(set get)
get set 只针对属性,如果不需要进行逻辑处理可引入 lombok
后在类名前添加 @Data
注解隐式声明,针对与需要做逻辑处理的显示声明,编写逻辑处理代码
boolean 类型的属性生成的 get set 方法中 set 会变为 is
pom.xml引入 lombok 依赖后,在类名前添加 @Data
注解
1 2 3 4 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
示例 1 2 3 4 5 6 7 <!-- 依赖 --> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package com.tester.ada.trait.encapsulation;import lombok.Data;@Data public class MemberTester { private String phone; private String password; public void setPhone (String phone) { if (11 == phone.length()) this .phone = phone; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.tester.ada.trait.encapsulation;public class BorrowerTester extends MemberTester { public static void main (String[] args) { BorrowerTester link = new BorrowerTester (); link.setPhone("13888888888" ); System.out.println(link.getPhone()); } }
继承 简介
继承是 Java 三大特性的另一大特性,继承是从已有的类中派生出新的类,新的类能吸收已有类的属性和行为,并能扩展新的能力
一个类 A 继承 B 可以通过 extends 来实现(extends 翻译为扩展,我们通俗的称为继承)
一个不由任何类派生出来的类称为基类(派生类)
,一个派生类(子类)最近的上层类称为该类的父类
,从某一个派生类出来的类称为该类的子类
派生类(子类)与父类之间是一个子与父的关系,子跟父之间的关系是 is a 的关系,父类和子类是 has a 的关系
水果类 –>热带水果、亚热带水果 –>芒果、香蕉、火龙果(热带水果)
芒果 extends 热带水果 –> 子类 extends 父类 –> 子类 is a 父类 –> 芒果 is a 热带水果 = 热带水果 has a 芒果
Java 中子类不能获得父类的构造方法
语法 1 2 3 修饰符 class SubClass extends SuperClass { }
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package com.tester.ada.trait.inherit;import lombok.Data;@Data public class MemberTester { private String phone; private String pwd; private String regName; private double amount; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package com.tester.ada.trait.inherit;import lombok.Data;@Data public class BorrowerTester extends MemberTester { private boolean hasCar; private boolean hasHouse; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package com.tester.ada.trait.inherit;import lombok.Data;@Data public class InvestTester extends MemberTester { public void invest (double doubleValue) { System.out.println("调用:InvestTester.invest()" +"投资【" +doubleValue+"】元成功" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.tester.ada.trait.inherit;public class Tester1 { public static void main (String[] args) { InvestTester ada = new InvestTester (); ada.setAmount(10000 ); System.out.println(ada.getAmount()); ada.invest(3000 ); BorrowerTester dream = new BorrowerTester (); dream.setPhone("13555555555" ); dream.setHasCar(true ); System.out.println(dream.getPhone()); System.out.println(dream.isHasCar()); } }
多态 概念
不同的对象对应相同的方法表现出不同的特征和响应:如对于自行车和汽车他们都定义了刹车的方法,但是它们的刹车方式却完全不同,又比如动物类都有吃东西的方法,食肉动物吃东西的方法是吃肉食,食草动物吃东西的方法是吃草 蔬菜,乐器都会发出声音,不同乐器演奏出来的表现形式各不相同
用父类类型来接受子类
的对象,Java 通过方法重写
来实现多态
通过方法重写,子类可以实现父类的某些方法,使其具有自己的特征
(例如都是人类,别人实现一个小目标是一个亿,我们的一个小目标是换个手机,因此要重写“富人”和“穷人”实现目标的方法,使其具有自己的特征)
通过方法重写 相同的对象(变量),执行同一个方法表现出不同的行为特征,就称为多态
多态的优点:提高代码的复用性,简化代码
缘由
在很对时候会使用父类类型接受子类对象,但是父类类型又没有实现该方法,会出现报错,如下图所示
当然可以直接在父类中实现该方法解决报错,不过很多时候子类有自己的实现方式,比如充值的方法,针对于投资人是充值投资,针对于借款人是充值还款,因此要在子类中实现自己的充值方法
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package com.tester.ada.trait.Polymorphism;import lombok.Data;@Data public class MemberTester { private String phone; private String pwd; private String regName; private double amount; public void recharge (double doubleValue) { if (doubleValue < 100 || doubleValue > 500000 ) { System.out.println("MemberTester.recharge():" + "充值失败,金额必须大于等于 100 或小于等于 50万" ); } else { this .amount += doubleValue * 1.5 ; System.out.println("MemberTester.recharge():" + "尊贵的客户恭喜您获得 1.5 倍翻倍机会,当前累计充值【" + this .getAmount() + "】成功,感谢您的使用" ); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.tester.ada.trait.Polymorphism;public class BorrowerTester extends MemberTester { public void recharge (double doubleValue) { if (doubleValue < 100 || doubleValue > 500000 ) { System.out.println("BorrowerTester.recharge():" + "充值失败,金额必须大于等于 100 或小于等于 50万" ); } else { this .setAmount(this .getAmount() + doubleValue); System.out.println("BorrowerTester.recharge():" + "还款【" + doubleValue + "】成功,累计还款" + this .getAmount() + "元,您的信誉保持良好可继续申请借贷" ); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.tester.ada.trait.Polymorphism;public class InvestTester extends MemberTester { public void recharge (double doubleValue) { if (doubleValue < 100 || doubleValue > 500000 ) { System.out.println("InvestTester.recharge():" + "充值失败,金额必须大于等于 100 或小于等于 50万" ); } else { this .setAmount(this .getAmount() + doubleValue); System.out.println("InvestTester.recharge():" + "充值【" + doubleValue + "】成功,累计充值" + this .getAmount() + "元,您可以去投资赚钱收益了" ); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package com.tester.ada.trait.Polymorphism;public class Tester1 { public static void main (String[] args) { MemberTester link = new MemberTester (); link.recharge(1000 ); link.recharge(2000 ); MemberTester ada = new InvestTester (); ada.recharge(100 ); ada.recharge(1000 ); MemberTester dream = new BorrowerTester (); dream.recharge(1000 ); dream.recharge(5000 ); ### HashSet + `无序` `不可重复` + 支持的数据类型为引用类型(类、数组)(如果添加基本数据类型会自动装箱) ```java package com.tester.ada.common.gather.HashSet;import java.util.HashSet;public class HashSetTester { public static void main (String[] args) { HashSet<String> set = new HashSet <String>(); set.add("ada" ); set.add("ada" ); set.add("link" ); set.add("dream" ); System.out.println(set.size()); System.out.println(set.contains("link" )); System.out.println(set.isEmpty()); Object[] objs = set.toArray(); for (Object obj : objs) { System.out.println(obj); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.tester.ada.common.gather.HashSet;import java.util.HashSet;import java.util.Iterator;public class HashSetTester1 { public static void main (String[] args) { HashSet<String> nations = new HashSet <String>(); nations.add("china" ); nations.add("USA" ); nations.add("Japan" ); System.out.println("===============forEach===============" ); for (String nation : nations) { System.out.println(nation); } System.out.println("===============迭代器一===============" ); for (Iterator nation1 = nations.iterator(); nation1.hasNext(); ) { System.out.println(nation1.next()); } System.out.println("===============迭代器二===============" ); Iterator nation2 = nations.iterator(); while (nation2.hasNext()) { System.out.println(nation2.next()); } } }
示例二
其实示例一种虽然实现了多态,但是并没有发挥出多态的优点:提高代码的复用性,简化代码
也就是说这里的 recharge() 方法写了三遍实现,但是业务逻辑几乎一致(这里不考虑 1.5 倍翻倍了),因此需要优化代码示例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package com.tester.ada.trait.Polymorphism;import lombok.Data;@Data public class MemberTester1 { private String phone; private String pwd; private String regName; private double amount; public boolean recharge (double doubleValue) { if (doubleValue < 100 || doubleValue > 500000 ) { System.out.println("MemberTester.recharge():" + "充值失败,金额必须大于等于 100 或小于等于 50万" ); return false ; } else { this .setAmount(this .getAmount() + doubleValue); return true ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package com.tester.ada.trait.Polymorphism;public class InvestTester1 extends MemberTester1 { @Override public boolean recharge (double doubleValue) { boolean flag = super .recharge(doubleValue); if (flag){ System.out.println("InvestTester1.recharge():" + "充值【" + doubleValue + "】成功,累计充值" + this .getAmount() + "元,您可以去投资赚钱收益了" ); } return flag; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package com.tester.ada.trait.Polymorphism;public class BorrowerTester1 extends MemberTester1 { @Override public boolean recharge (double doubleValue) { boolean flag = super .recharge(doubleValue); if (flag) { System.out.println("BorrowerTester1.recharge():" + "还款【" + doubleValue + "】成功,累计还款" + this .getAmount() + "元,您的信誉保持良好可继续申请借贷" ); } return flag; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.tester.ada.trait.Polymorphism;public class Tester2 { public static void main (String[] args) { MemberTester1 link = new MemberTester1 (); link.recharge(1000 ); link.recharge(2000 ); MemberTester1 ada = new InvestTester1 (); ada.recharge(100 ); ada.recharge(1000 ); MemberTester1 dream = new BorrowerTester1 (); dream.recharge(1000 ); dream.recharge(5000 ); } }
常用 String API 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 package com.tester.ada.common.string;import java.nio.charset.StandardCharsets;public class StringTester { public static void main (String[] args) { String str = new String ("hello" ); System.out.println(str.startsWith("hel" )); System.out.println(str.endsWith("o" )); System.out.println(str.substring(1 )); System.out.println(str.substring(2 , 3 )); String str1 = "ada,link,test" ; String[] str2 = str1.split("," ); for (String str3 : str2) { System.out.print(str3 + "\t" ); } System.out.println(); System.out.println(str1.indexOf("a" )); System.out.println(str1.lastIndexOf("a" )); System.out.println(str.contains("llo" )); System.out.println(str.equals("Hello" )); System.out.println(str.equalsIgnoreCase("HELlo" )); System.out.println("a" .compareToIgnoreCase("c" )); System.out.println("he" .concat("llo" )); System.out.println("" .isEmpty()); System.out.println(" ada " .trim()); System.out.println("link" .length()); System.out.println("adaTester" .toCharArray()[0 ]); System.out.println(str.charAt(str.length() - 1 )); System.out.println(new String ("中国" .getBytes(StandardCharsets.UTF_8))); System.out.println("aDA" .toUpperCase()); System.out.println("aDA" .toLowerCase()); System.out.println("ada" .replace("a" , "c" )); System.out.println("ada" .replaceFirst("a" , "b" )); System.out.println("ada" .replaceAll("a" , "b" )); System.out.println(String.valueOf("hello ada" )); } }
常量
对于一些固定不变的属性可通过 public static final
修饰为常量
加了static
后只能在 static
方法中访问
final
属性不可修改 常量不能生成 set 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.tester.ada.common.constant;public class FinalTester { private static final String COUNTRY = "中国" ; public static final String LOCATION = "Earth" ; public static void main (String[] args) { System.out.println(FinalTester.COUNTRY); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package com.tester.ada.common.constant;public class Tester { public static void main (String[] args) { System.out.println(FinalTester.LOCATION); } }
集合类 简介
Java 的集合类是特别有用的工具类
可以存储多个对象(保存的数据类型需要是引用数据类型)
常见的有: ArrayList、HashSet、HashMap
ArrayList
ArrayList 可变数组,数组列表,有序
可重复
如果是一维数组是需要声明长度的,也就是固定长度,有时候并不满足要求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package com.tester.ada.common.gather.ArrayList;import java.util.ArrayList;public class ArrayListTester { public static void main (String[] args) { String[] names = new String [40 ]; names[0 ] = "ada" ; names[1 ] = "link" ; names[39 ] = "Shadow" ; ArrayList<String> arrayList = new ArrayList <String>(); arrayList.add("ada" ); arrayList.add("link" ); arrayList.add("Shadow" ); System.out.println(arrayList.get(1 )); arrayList.forEach(name -> System.out.println(name)); arrayList.remove(1 ); System.out.println(arrayList.get(1 )); System.out.println(arrayList.size()); System.out.println(arrayList.isEmpty()); System.out.println(arrayList.contains("link" )); arrayList.set(1 , "dream" ); System.out.println(arrayList.get(1 )); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package com.tester.ada.common.gather.ArrayList; import java.util.ArrayList; import java.util.Iterator; /** * @author ada * @ClassName ArrayListTester1 * @Description ArrayList 遍历 * @Computer Macbook pro * @Date 2021/12/23 22:37 */ public class ArrayListTester1 { public static void main(String[] args) { ArrayList<Integer> arrayList = new ArrayList<Integer>(); arrayList.add(1); arrayList.add(3); arrayList.add(5); System.out.println("---------------foreach---------------"); for (Integer number : arrayList) { System.out.println(number); } System.out.println("---------------普通for循环---------------"); for (int i = 0; i < arrayList.size(); i++) { System.out.println(arrayList.get(i)); } System.out.println("---------------Lambda表达式一---------------"); arrayList.forEach(number -> { System.out.println(number); //写执行的逻辑 }); System.out.println("---------------Lambda表达式二---------------"); arrayList.forEach(System.out::println); System.out.println("---------------迭代器---------------"); // 迭代器 hasNext-->如果有下一个元素就为 true next->得到下一个元素,并且会自动去进行移动,类似 i++改变循环条件 for (Iterator iterator = arrayList.iterator(); iterator.hasNext(); ) { Integer ints = (Integer) iterator.next(); System.out.println(ints); } } }
HashSet
无序
不可重复
支持的数据类型为引用类型(类、数组)(如果添加基本数据类型会自动装箱)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package com.tester.ada.common.gather.HashSet;import java.util.HashSet;public class HashSetTester { public static void main (String[] args) { HashSet<String> set = new HashSet <String>(); set.add("ada" ); set.add("ada" ); set.add("link" ); set.add("dream" ); System.out.println(set.size()); System.out.println(set.contains("link" )); System.out.println(set.isEmpty()); Object[] objs = set.toArray(); for (Object obj : objs) { System.out.println(obj); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.tester.ada.common.gather.HashSet;import java.util.HashSet;import java.util.Iterator;public class HashSetTester1 { public static void main (String[] args) { HashSet<String> nations = new HashSet <String>(); nations.add("china" ); nations.add("USA" ); nations.add("Japan" ); System.out.println("===============forEach===============" ); for (String nation : nations) { System.out.println(nation); } System.out.println("===============迭代器一===============" ); for (Iterator nation1 = nations.iterator(); nation1.hasNext(); ) { System.out.println(nation1.next()); } System.out.println("===============迭代器二===============" ); Iterator nation2 = nations.iterator(); while (nation2.hasNext()) { System.out.println(nation2.next()); } } }
HashMap
以键值对的形式来保存数据
键不可以重复,重复时,后者键值覆盖前者
键和值支持的数据类型为引用类型
Map 可以描述任何一个对象信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.tester.ada.common.gather.HashMap;import java.util.Collection;import java.util.HashMap;import java.util.Set;public class HashMapTester { public static void main (String[] args) { HashMap<String, Object> info = new HashMap <String, Object>(); info.put("name" , "ada" ); info.put("age" , 18 ); info.put("age" , 25 ); info.put("Profession" , "测试工程师" ); System.out.println(info.get("age" )); info.remove("name" ); System.out.println(info.size()); System.out.println(info.containsKey("name" )); System.out.println(info.containsValue("工程师" )); Set<String> allKey = info.keySet(); System.out.println(allKey); Collection<Object> allValues = info.values(); System.out.println(allValues); info.keySet().forEach(key -> System.out.println(key + "-->" + info.get(key))); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package com.tester.ada.common.gather.HashMap;import java.util.HashMap;public class HashMapTester1 { public static void main (String[] args) { HashMap<String, Object> map = new HashMap <String, Object>(); map.put("name" , "ada" ); map.put("age" , 25 ); map.put("Profession" , "测试工程师" ); System.out.println("===============forEach===============" ); for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); } System.out.println("===============Lambda 表达式===============" ); map.forEach((key, value) -> { System.out.println(key + "=" + value); }); } }
Json 简介
JSON (JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式
对象表示为键值对
数据由逗号分割
花括号保存对象
1 2 3 4 5 6 { "name" : "ada" , "age" : "25" , "gender" : "男" , "Profession" : "测试工程师" }
1 2 3 4 5 [ { "name" : "ada" , "age" : "25" , "gender" : "男" , "Profession" : "测试工程师" } , { "name" : "ada1" , "age" : "26" , "gender" : "男" , "Profession" : "测试工程师1" } , { "name" : "ada2" , "age" : "27" , "gender" : "男" , "Profession" : "测试工程师2" } ]
生成实体类
除了手写还可以通过一些插件(GsonFormatPlus
)快速生成实体类(在插件中搜索安装)
创建实体类,在类中右键–>生成–>GsonFormatPlus–>粘贴 json 格式文本(GsonFormatPlus中可设置成 Lombok PS:pom.xml 需要先引入)
@NoArgsConstructor 生成一个无参的构造函数
@Data 生成 get set 方法
转换
采用第三方工具 fastJson 或 gson(这里以 fastJson 为例)
fastJson 需要在 pom 中引入
1 2 3 4 5 <dependency > <groupId > com.alibaba</groupId > <artifactId > fastjson</artifactId > <version > ${fastjson.version}</version > </dependency >
将Json字符串转对象 JSONObject.parse()
将Json数组格式字符串转对象 JSONObject.parseArray()
将对象转换为字符串
json 字符串转 Map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package com.tester.ada.common.json;import com.alibaba.fastjson.JSONObject;import java.util.Map;public class Json2Map { public static String strJson = "{\n" + " \"name\": \"ada\",\n" + " \"age\": \"25\",\n" + " \"gender\": \"男\",\n" + " \"Profession\": \"测试工程师\"\n" + "}" ; public static void main (String[] args) { Map map = (Map)JSONObject.parse(strJson); System.out.println(map); } }
Json 字符串转对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.tester.ada.common.json;import lombok.Data;import lombok.NoArgsConstructor;@NoArgsConstructor @Data public class User { private String name; private String age; private String gender; private String profession; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.tester.ada.common.json;import com.alibaba.fastjson.JSONObject;public class Json2Object { public static void main (String[] args) { User users = JSONObject.parseObject(Json2Map.strJson, User.class); System.out.println(users); System.out.println(users.getName()); } }
Maven 简介
Maven 中央仓库 Maven 这个项目维护了一个网站,在这个上面维护了非常多开源的 jar 包,并且维护了每个 jar 包的版本便于开发者们去下载使用
Maven:解决协同合作时版本问题 协同合作时传输问题
Maven 是一个项目管理工具,它包含了一个项目对象模型(Project Object Model)–> pom.xml
作用:项目构建(编译
打包
发布
测试
等等)
目前大部分企业在在做项目(Java)时的首选项目构建管理工具(部分较老的企业也有用 Ant,Android 一般采用gradle
)
IDE 一般都自带有 Maven,如果没有集成开发环境需要自行下载安装配置环境变量(不管哪种方式使用,做好都修改下镜像源为国内源,本地仓库地址设置为非系统盘–>修改 settings.xml 文件 mirrors
localRepository
)
Maven 添加依赖时的流程(比如我们 pom.xml 文件中添加了 fastjson 的依赖配置)
查看本地仓库是否有指定的 fastjson 的 jar 包
如果有直接引入,如果没有自动从远程仓库搜索 fastjson 的 jar 包(如果远程仓库找不到就会报错,有可能版本不对,或者网络原因,或者在私服,或者自己打的 jar包)
建立 Maven 项目时将从本地资源获得 Maven 的本地资源库依赖资源
如果没找到,则从默认的 Maven(或者自己配置)的远程仓库查找下载
POM
pom(Project Object Model)即项目对象模型,是 Maven 工作的基本单位
位于项目目录中的 xml 文件:pom.xml
pom.xml其中可以包含项目构建的各种配置信息
每个项目只有一个
Maven 的特点
可以使用 Maven 来编译你的代码
项目打包也可以使用 Maven 来完成
Maven 可以实现模块化管理
Maven 可以在线管理依赖
,项目依赖也很方便获取
Maven 提供了一些丰富的插件,方便项目持续集成
新建 Maven 工程参数
groupId:分组,一般填写组织机构,如 com.incar
artifactId:项目包名(项目打包成 jar 包的 ID,或者说 jar 包名字)
version:版本
name: Maven工程名称
packaging:打包方式 (jar war pom)我用的 pom
<relativePath>../pom.xml</relativePath>:继承父类的依赖(如果是多个子模块都需要用到的依赖,可以在父模块引用依赖子模块添加该标签即可)
1 2 3 4 5 6 <groupId > com.adalucky</groupId > <artifactId > automation</artifactId > <version > V1.0.0</version > <name > endpoint</name > <packaging > pom</packaging > <description > Demo project for Spring Boot</description >
Maven 项目结构
src/main/java:一般是开发人员写代码的目录
src/main/resource:开发人员放项目资源的目录
src/test/java:放单元测试或测试人员写代码的目录
src/main/resource:放测试资源的目录
Maven Dependencies:通过 Maven 下载下来的项目依赖包存放的目录
target:存放构建后文件的目录
文件解析 properties解析
Properties
类是 java.util
提供的工具类
当前类名.class.getResourceAsStream
当前类读取一个文件,并且转换为输入流
文件路径的更路径是/src/main/resources (可在 idea 的配置文件中修改)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 package com.tester.ada.Parsing.properties;import java.io.IOException;import java.io.InputStream;import java.util.Properties;public class PropertiesTester { private static Properties properties = new Properties (); public static void main (String[] args) { InputStream in = PropertiesTester.class.getResourceAsStream("/config/user.properties" ); try { properties.load(in); } catch (IOException e) { e.printStackTrace(); } System.out.println(properties.getProperty("name" )); System.out.println(properties.getProperty("age" )); System.out.println(properties.getProperty("gradle" )); System.out.println(properties.getProperty("flag" )); System.out.println(properties.getProperty("profession" )); } public static String get (String key) { return properties.getProperty(key); } public static Integer getInteger (String key) { String value = get(key); return null == value ? null : Integer.valueOf(value); } public static Boolean getBoolean (String key) { String value = get(key); return null == value ? null : Boolean.valueOf(value); } }
Xml 解析 简介
XML:( Extensible Markup Language ) 可扩展的标记语言,类似于 html 都是标记语言(可以写逻辑处理的叫编程语言 比如 js py等等)
特点
可扩展性,在遵循 xml 语法的前提下支持自定义和修改
标记语言,具有结构性,意味着也是类似于 html 中的标签来定义文档
xml 在姓名中的使用更多的是作为数据载体
而出现的,xml 和 json 都是一种数据交互格式
非常适合万维网数据 传输
,提供统一方法描述和交换结构化数据
xml 与 html 的区别:xml 是作为数据传输的工具,是一种数据载体, html 是数据展示的工具(展示成一个网页)
文档结构
xml 的文档结构跟 HTML 类似,也是一种树形结构,从上往下发展
父、子以及同胞等术语用于描述元素之间的关系
父元素拥有子元素
相同层级上的子元素称为同胞(兄弟或姐妹)
所有的元素都可以有文本内容和属性(类似 html)
语法
xml 声明语法:元素的属性值,必须要用双引号 “ “引起来 注释使用 <!-- 注释内容 -->
1 <?xml version="1.0" encoding="utf-8" ?>
根元素:
xml 必须包含根元素
,它是所有其它元素的父元素,比如一下实例中 person 就是根元素
1 2 3 4 5 <person > <name > ada</name > <age > 25</age > <gender > 男</gender > </person >
所有元素标签成对出现
大小写敏感
嵌套使用(注意嵌套顺序)
dom4j 解析技术 dom4j : Document Object Model for Java
1 2 3 4 5 6 <dependency > <groupId > dom4j</groupId > <artifactId > dom4j</artifactId > <version > ${dom4j.version}</version > </dependency >
创建解析器 SaxReader 对象
获取document 对象
获取根元素
获取根元素下的子元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?xml version="1.0" encoding="UTF-8" ?> <Users > <user_1 cid ="1" > <name > John</name > <email > john@example.com</email > <age > 18</age > </user_1 > <user_2 cid ="2" > <name > ada</name > <email > ada@example.com</email > <age > 22</age > </user_2 > <user_3 cid ="3" > <name > link</name > <email > link@example.com</email > <age > 31</age > </user_3 > </Users >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package com.tester.ada.Parsing.xml.entity;import lombok.Data;@Data public class User { private String cid; private String name; private String email; private String age; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 package com.tester.ada.Parsing.xml;import com.tester.ada.Parsing.xml.entity.User;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import java.util.ArrayList;import java.util.List;public class XMLTester { private static Document document; private static List<User> users = new ArrayList <User>(); public static void main (String[] args) { readXml("/config/user.xml" ).forEach(user -> System.out.println(user)); } public static List<User> readXml (String xmlPath) { SAXReader reader = new SAXReader (); try { document = reader.read(XMLTester.class.getResourceAsStream(xmlPath)); } catch (DocumentException e) { e.printStackTrace(); } Element rootElement = document.getRootElement(); List<Element> elements = rootElement.elements(); elements.forEach(element -> { User user = new User (); String elementName = element.getName(); String idAttr = element.attribute("cid" ).getValue(); user.setCid(idAttr); List<Element> userInfoElements = element.elements(); userInfoElements.forEach(userInfoElement -> { String tagName = userInfoElement.getName(); String tagValue = userInfoElement.getStringValue(); if ("name" .equals(tagName)) { user.setName(tagValue); } else if ("age" .equals(tagName)) { user.setAge(tagValue); } else if ("email" .equals(tagName)) { user.setEmail(tagValue); } else if ("cid" .equals(tagName)) { user.setCid(tagValue); } }); users.add(user); }); return users; } }
反射
在上面的 xml 解析时如果每次在 xml 的子节点中新增了标签,那么就需要再去添加一个 if else 做判断,不好维护,因此可通过反射技术实现通用性处理
反射 –> 运行时编程 –> 通用性处理
概念
Java 反射机制是在运行状态中对任意一个类都能够知道这个类的所有属性和方法
对于任意一个对象都能够调用它的任意一个方法和属性
这种动态获取信息
以及动态调用对象方法
的功能称为 Java 语言的反射机制
本质
根据类的自己吗 class 文件获取一个类的细节,包括构建出来,通过对象去调用方法、操作属性
关键字:反射
反向获取
映射
Java 中每一个类都有一个 class 对象,可以通过这个 class 对象获取它对应的属性和方法,然后再用这个对象的类去调用获取的方法
在 Java 中 Class
可以用来描述所有的类 Method
可以描述所有的方法
反射的实现
1 Class<User> clazz = Class.forName("com.tester.ada.Parsing.entity.User" );
1 User user= clazz.newInstance();
1 2 String methodName = "set" +(name.chaeAt(0 )+"" ).toUpperCase()+name.substring(1 );Method method = clazz.getMethod(methodName,String.class);
1 method.invoke(user,value);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package com.tester.ada.Parsing.Mapping;import com.tester.ada.Parsing.xml.entity.User;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class MappingTest { public static void demo () { try { Class<User> clazz = (Class<User>) Class.forName("com.tester.ada.Parsing.xml.entity.User" ); User user = clazz.newInstance(); String methodName = "set" + "Name" ; Method method = clazz.getMethod(methodName, String.class); method.invoke(user, "调用反射设值" ); System.out.println(user.getName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } public static void main (String[] args) { MappingTest.demo(); } }
获取 Class 对象
Class 类:用于描述类的一个类(属性、方法、构造器)
Class 对象
封装了所有对应的类的细节信息
将class 文件读入内存,则会创建一个 Class 对象
Class 对象是 jvm 自动化创建的,一个类只产生一个 Class 对象
运行时编程
获得 Class 对象(获取 Test类的 Class)
通过对象调用 getClass 方法,例创建 test 对象:test.getClass();
通过类名去获取:Test.class;
通过类路径注册
获取:Class.forName(“com.tester.ada.Parsing.xml.entity.User”);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package com.tester.ada.Parsing.Mapping;public class MappingTest2 { public static void demo () { Test test = new Test (); Class clazz1 = test.getClass(); Class clazz2 = Test.class; Class clazz3 = null ; try { clazz3 = Class.forName("com.tester.ada.Parsing.Mapping.Test" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println(clazz1 == clazz2); System.out.println(clazz2 == clazz3); } public static void main (String[] args) { MappingTest2.demo(); } }
获取类名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package com.tester.ada.Parsing.Mapping;public class MappingTest3 extends MappingTest { public static void demo () { Class clazz = MappingTest3.class; System.out.println("当前类名【" + clazz.getName() + "】" ); System.out.println("当前类的包名【" + clazz.getPackage().getName() + "】" ); System.out.println("是否为接口【" + clazz.isInterface() + "】" ); System.out.println("父类类名【" + clazz.getSuperclass().getName() + "】" ); } public static void main (String[] args) { MappingTest3.demo(); } }
获取字段 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package com.tester.ada.Parsing.Mapping;import java.lang.reflect.Field;import java.util.Arrays;public class MappingTest4 { public static void demo () { Class clazz = Test.class; Field[] publicFields = clazz.getFields(); Arrays.asList(publicFields).forEach(field -> System.out.println("public字段:" + field)); Field[] allFields = clazz.getDeclaredFields(); Arrays.asList(allFields).forEach(field -> System.out.println("所有字段:" + field)); Arrays.asList(allFields).forEach(field -> System.out.println("字段名:" + field.getName() + "\t字段类型:" + field.getType() + "\t修饰符:" + field.getModifiers())); try { Field field = clazz.getField("code" ); System.out.println("+++++++++++++++++++++++获取指定字符串的属性+++++++++++++++++++++++" ); System.out.println("字段名:" + field.getName() + "\t字段类型:" + field.getType() + "\t修饰符:" + field.getModifiers()); } catch (NoSuchFieldException e) { e.printStackTrace(); } } public static void main (String[] args) { demo(); } }
获取方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package com.tester.ada.Parsing.Mapping;import java.lang.reflect.Method;import java.util.Arrays;public class MappingTest5 { public static void demo () { Class clazz = Test.class; Method[] methods = clazz.getMethods(); Arrays.asList(methods).forEach(method -> System.out.println("1.获取的是类public方法:" + method)); Method[] allMethod = clazz.getDeclaredMethods(); Arrays.asList(allMethod).forEach(method -> System.out.println("2.获取的是类自身声明的所有方法:" + method)); try { Method demo1Method = clazz.getDeclaredMethod("demo1" , String.class, Integer.class); System.out.println("3.方法的修饰符:" + demo1Method.getModifiers() + "\t方法的名称:" + demo1Method.getName() + "\t方法的返回值类型:" + demo1Method.getReturnType() + "\t方法的参数个数:" + demo1Method.getParameterCount() + "\t方法的参数类型:" + Arrays.asList(demo1Method.getParameterTypes()).toString()); } catch (NoSuchMethodException e) { e.printStackTrace(); } Method[] publicMethod = clazz.getMethods(); Arrays.asList(publicMethod).forEach(method -> System.out.println("4.获取的是类和继承实现的public方法:" + method)); } public static void main (String[] args) { demo(); } }
方法的调用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package com.tester.ada.Parsing.Mapping;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class MappingTest6 { public static void demo () { Class clazz = Test.class; try { Method method = clazz.getMethod("demo4" ); System.out.println("静态方法用 null 调用:" + method.invoke(null )); System.out.println("静态方法用对象调用:" + method.invoke(clazz.newInstance())); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) { e.printStackTrace(); } } public static void main (String[] args) { demo(); } }
获取构造函数及创建对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 package com.tester.ada.Parsing.Mapping;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.util.Arrays;public class MappingTest7 { public static void demo () { Class clazz = Test.class; Constructor[] publicConstructors = clazz.getConstructors(); Arrays.asList(publicConstructors).forEach(constructor -> System.out.println(constructor)); try { Constructor testConstructors = clazz.getConstructor(String.class, Integer.class, Integer.class); System.out.println("三个参数构造函数初始化对象:" + testConstructors.newInstance("str" , 15 , 20 )); System.out.println("构造函数名称:" + testConstructors.getName()); System.out.println("构造函数参数列表:" + Arrays.asList(testConstructors.getParameterTypes()).toString()); System.out.println("构造函数参数个数:" + testConstructors.getParameterTypes().length); System.out.println("构造函数修饰符:" + testConstructors.getModifiers()); } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } try { Constructor tester = clazz.getConstructor(null ); System.out.println("无参构造函数初始化对象:" + tester.newInstance()); } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } public static void main (String[] args) { demo(); } }
创建对象的两种方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package com.tester.ada.Parsing.Mapping;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class MappingTest8 { public static void demo () { Class clazz = Test.class; try { Object obj = clazz.newInstance(); System.out.println(obj); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } try { Constructor c = clazz.getConstructor(String.class, Integer.class, Integer.class); System.out.println(c.newInstance("a" , 20 , 35 )); } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } public static void main (String[] args) { demo(); } }
Excel 解析
采用阿里巴巴的开源工具类 easyExcel
引入依赖 lombok easyexcel
1 2 3 4 5 6 7 8 9 10 <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <optional > true</optional > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > easyexcel</artifactId > <version > ${easyexcel.version}</version > </dependency >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 package com.tester.ada.Parsing.excel.service;import com.alibaba.excel.EasyExcel;import com.alibaba.excel.ExcelReader;import com.alibaba.excel.context.AnalysisContext;import com.alibaba.excel.event.AnalysisEventListener;import com.alibaba.excel.read.builder.ExcelReaderBuilder;import com.alibaba.excel.support.ExcelTypeEnum;import java.util.Map;public class Dome { public static void demo () { ExcelReaderBuilder readerBuilder = EasyExcel.read(); readerBuilder.file("ada/src/main/resources/excel/easyExcel.xlsx" ); readerBuilder.sheet(0 ); readerBuilder.autoCloseStream(true ); readerBuilder.excelType(ExcelTypeEnum.XLSX); readerBuilder.registerReadListener(new AnalysisEventListener () { @Override public void invoke (Object o, AnalysisContext analysisContext) { System.out.println(o); } @Override public void doAfterAllAnalysed (AnalysisContext analysisContext) { System.out.println("数据读取完毕" ); } }); ExcelReader reader = readerBuilder.build(); reader.readAll(); reader.finish(); } public static void demo1 () { ExcelReaderBuilder readerBuilder = EasyExcel.read(); readerBuilder.file("ada/src/main/resources/excel/easyExcel.xlsx" ); readerBuilder.sheet(0 ); readerBuilder.autoCloseStream(true ); readerBuilder.excelType(ExcelTypeEnum.XLSX); readerBuilder.registerReadListener(new AnalysisEventListener <Map<Integer, String>>() { @Override public void invoke (Map<Integer, String> integerStringMap, AnalysisContext analysisContext) { integerStringMap.forEach((k, v) -> { System.out.print(k + ":" + v + "\t" ); }); System.out.println("" ); } @Override public void doAfterAllAnalysed (AnalysisContext analysisContext) { System.out.println("数据读取完毕" ); } }); ExcelReader reader = readerBuilder.build(); reader.readAll(); reader.finish(); } public static void main (String[] args) { demo1(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package com.tester.ada.Parsing.excel.service;import com.alibaba.excel.EasyExcel;import com.alibaba.excel.context.AnalysisContext;import com.alibaba.excel.event.AnalysisEventListener;import java.util.LinkedList;import java.util.List;import java.util.Map;public class DomePro { public static void demo () { List<Map<Integer, String>> dataList = new LinkedList <Map<Integer, String>>(); EasyExcel.read("ada/src/main/resources/excel/easyExcel.xlsx" ) .sheet() .registerReadListener(new AnalysisEventListener <Map<Integer, String>>() { @Override public void invoke (Map<Integer, String> integerStringMap, AnalysisContext analysisContext) { dataList.add(integerStringMap); dataList.forEach(maps -> { maps.forEach((k, v) -> System.out.print(k + ":" + v + "\t" )); System.out.println("" ); }); } @Override public void doAfterAllAnalysed (AnalysisContext analysisContext) { System.out.println("读取完毕" ); } }).doRead(); } public static void main (String[] args) { demo(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 package com.tester.ada.Parsing.excel.entity;public abstract class ExecelData { }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package com.tester.ada.Parsing.excel.entity;import com.alibaba.excel.annotation.ExcelProperty;import lombok.Data;import java.util.Date;@Data public class EasyExcelEntity extends ExecelData { @ExcelProperty("ID") private String id; @ExcelProperty("用户名") private String name; @ExcelProperty("邮箱") private String email; @ExcelProperty("性别") private String gander; @ExcelProperty("积分") private Integer score; @ExcelProperty("IP") private String IP; @ExcelProperty("登录次数") private Integer count; @ExcelProperty("加入时间") private Date date; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 package com.tester.ada.Parsing.excel.service;import com.alibaba.excel.EasyExcel;import com.alibaba.excel.context.AnalysisContext;import com.alibaba.excel.event.AnalysisEventListener;import com.alibaba.excel.support.ExcelTypeEnum;import com.alibaba.excel.write.builder.ExcelWriterBuilder;import org.apache.poi.ss.formula.functions.T;import java.util.LinkedList;import java.util.List;public class easyExcelService { public static <T> List<T> readExcel (String Source_Path, Integer sheetIndex, Class<T> clazz) { if (isExcel(Source_Path)) { List<T> readList = new LinkedList <>(); EasyExcel.read(Source_Path) .head(clazz) .sheet(sheetIndex) .registerReadListener(new AnalysisEventListener <T>() { @Override public void invoke (T data, AnalysisContext analysisContext) { readList.add(data); } @Override public void doAfterAllAnalysed (AnalysisContext analysisContext) { System.out.println("读取完毕" ); } }).doRead(); return readList; } return null ; } public static void writeExcel (String target_Path, String Sheet_name, List<T> execelDataList, Class clazz) { ExcelWriterBuilder head = EasyExcel.write(target_Path) .head(clazz); if (isExcel(target_Path)) { head.excelType(ExcelTypeEnum.XLS); } else { head.excelType(ExcelTypeEnum.XLSX); } head.sheet(Sheet_name) .doWrite(execelDataList); System.out.println("数据已回写至【" + target_Path + "】" ); } public static boolean isExcel (String Source_Path) { String strType = Source_Path.substring(Source_Path.lastIndexOf("." )); if (".xls" .equalsIgnoreCase(strType) || ".xlsx" .equalsIgnoreCase(strType)) { return true ; } else { System.err.println("文件格式不是【xls、xlsx】格式" ); System.exit(0 ); } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package com.tester.ada.Parsing.excel.controlle;import com.tester.ada.Parsing.excel.entity.EasyExcelEntity;import com.tester.ada.Parsing.excel.service.easyExcelService;import org.apache.poi.ss.formula.functions.T;import java.util.List;public class ExcelControlle { public static <T> List<T> read (String Source_Path, Integer sheetIndex, Class<T> clazz) { return easyExcelService.readExcel(Source_Path, sheetIndex, clazz); } public static void write (String target_Path, String Sheet_name, List<T> execelDataList, Class clazz) { easyExcelService.writeExcel(target_Path, Sheet_name, execelDataList, clazz); } public static void main (String[] args) { List list = read("ada/src/main/resources/excel/easyExcel.xlsx" , 0 , EasyExcelEntity.class); System.out.println(list.get(0 )); write("/Users/ada/Desktop/easyExcel3.xlsx" , "第一页" , list, EasyExcelEntity.class); } }
异常 简介
异常:代码在运行过程中出现的非正常情况
异常处理:在程序出现异常时仍然可以正确执行完
异常机制
判断一门变成语言是都成熟的标准
可以让异常处理代码和正常业务逻辑分离,保证程序健壮性、容错性、优雅性
缺点是影响代码的可读性
抛出异常
方式一:在方法名后 throws 抛出异常的类型
方式二:在方法名后 throws 抛出 Exception 异常(父类异常,所有的异常都继承该类)
try…catch 补充知识 JRE 为什么需要安装 jdk
jdk 提供了编译器
jdk 提供了 java 运行环境(jre)
jre 下有很多现成的 jar包,这些 jar 包构成了 Java SE 的一个基本框架,实现了基本的服务
jre 下 jar 包的调用
jre 下的类
java.lang 下面的包不需要导包
其它类需要 import 导包
自己写的类
同一个 package 直接使用,无需显示导入
其它package 下需要 import 导包
其它项目工程
导出 jar 包–>提供开发套件 SDK
将 jar 包添加到私服/项目构建
重载重写 方法的重载
方法的重写
方法的重写也称为方法的覆写
出现继承中,子类重写父类的方法,实现多态(子类定义了和父类同名的方法)
注意:被重写的方法修饰符(访问权限)不能比父类更严格
修饰符 访问修饰符
将程序开发人员按角色区分可分为设计者与调用者
一个人可能同时又是设计者和调用者
修饰符的出现是为了控制设计者设计的类有哪些东西可以被调用者使用,哪些东西不能被调用者使用,从而实现访问控制,保护类里面一些重要的部分
private 默认修饰符 protected public 四种访问修饰符按照从左网易权限依次增大
访问位置
private
默认修饰符
protected
public
定义的类中
√
√
√
√
同一个包中
×
√
√
√
子类中
×
×
√
√
其它包中
×
×
×
√
非访问修饰符 static
static:静态
可以修饰变量、函数
类在加载到内存的时候最先加载进来的部分是静态的成员
静态成员的访问不需要依赖对象,可直接通过类名访问: 类名.static属性; 类名.static方法();
静态成员在内存中只保存一份,生命周期跟类保持一致,所以静态成员是共享的
一般不常改动的
数据工具类
适合声明为静态的
访问
不用实例化对象即可调用
static 方法只能访问 static 的属性和方法
非 static 的属性和方法使用实例化对象进行访问
final
final:最终的
被 final 修饰的变量它的值不能再做修改
被 final 修饰的函数,不能被重写
被 final 修饰的类,不能被继承
final声明一个常量,标识符全部使用大写
全局常量: public static final LP_LOGIN_BIN=”xxxxx”;
abstract
interface
interface:接口
1 2 3 public interface Action { public Event execute (RequestContext context) throws Exception; }
接口
使用 interface 关键字进行声明,类名前没有 class
接口是一种比抽象类还抽象的一种类
接口中只能定义方法不能有实现了的方法
在这个接口中,定义了一个没有具体实现的方法,方法名叫做execute(),返回类型是Event。如前面所述,接口中的方法都是没有实现的。这些方法的具体实现是在实现(implements)这个接口的类中给出的
实现接口通过 implements 关键字声明
抽象类和接口的比较 概述
一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了。当你需要再开发另一个相近的项目时,你以前的抽象层说不定还可以再次利用
面对对象的设计,复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用
说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了
既然面向对象设计的重点在于抽象,那Java接口和Java抽象类就有它存在的必然性了。
Java接口(interface)和Java抽象类(abstract class)代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。OOP面向对象的编程,如果要提高程序的复用率,增加程序 的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些有用的抽象类型作为你结构层次上的顶层。
Java接口和Java抽象类有太多相似的地方,又有太多特别的地方,究竟在什么地方,才是它们的最佳位置呢?把它们比较一下,你就可以发现了
区别
Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以(就是interface中只能定义方法,而不能有方法的实现,而在abstract class中则可以既有方法的具体实现,又有没有具体实现的抽象方法),这大概就是Java抽象类唯一的优点吧,但这个优点非常有用。如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个 新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行,这显然是Java接口的缺点
。倾向于使用抽象类,而不是接口,因为这更容易扩展。
一个抽象类的实现只能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的等级结构中,而由于Java语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣。在这一点上,Java接口的优势就出来了,任何一个实现了一个Java接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个Java接口,从而这个类就有了多种类型。(使用抽象类,那么继承这个抽象类的子类类型就比较单一,因为子类只能单继承抽象类;而子类能够同时实现多个接口,因为类型就比较多。接口和抽象类都可以定义对象,但是只能用他们的具体实现类来进行实例化。)
从第2点不难看出,Java接口是定义混合类型的理想工具,混合类表明一个类不仅仅具有某个主类型的行为,而且具有其他的次要行为。
结合1、2点中抽象类和Java接口的各自优势,具精典的设计模式就出来了:声明类型的工作仍然由Java接口承担,但是同时给出一个Java 抽象类,且实现了这个接口,而其他同属于这个抽象类型的具体类可以选择实现这个Java接口,也可以选择继承这个抽象类,也就是说在层次结构中,Java 接口在最上面,然后紧跟着抽象类
,这下两个的最大优点都能发挥到极至了。这个模式就是“缺省适配模式”。在Java语言API中用了这种模式,而且全都遵循一定的命名规范:Abstract +接口名。(A extends AbstractB implements interfaceC,那么A即可以选择实现(@Override)接口interfaceC中的方法,也可以选择不实现;A即可以选择实现(@Override)抽象类AbstractB中的方法,也可以选择不实现)
目的
Java接口和Java抽象类的存在就是为了用于具体类的实现和继承的,如果你准备写一个具体类去继承另一个具体类的话,那你的设计就有很大问题了。Java抽象类就是为了继承而存在的,它的抽象方法就是为了强制子类必须去实现的。
使用Java接口和抽象Java类进行变量的类型声明、参数是类型声明、方法的返还类型说明,以及数据类型的转换等。而不要用具体Java类进行变量的类型声明、参数是类型声明、方法的返还类型说明,以及数据类型的转换等。