一、重载(overload)
在一个类里面,方法名字相同,参数类型列表不相同,返回类型可以相同也可以不相同,称为方法重载.
- 方法重载与下列因素有关
1.参数个数不同
2.参数的类型不同
3.参数的多类型顺序不同 - 方法重载与下列因素无关
1.与参数的名称无关
2.与方法的返回值类型无关
public class Javastart {
public static void main(String[] args) {
System.out.println(sum(2, 1));
System.out.println(sum(2, 1, 2));
System.out.println(sum(2.0, 1.0));
}
public static int sum(int a, int b) {
return a + b;
}
public static int sum(int a, int b, int c) {
return a + b + c;
}
public static int sum(double a, double b) {
return (int)a + b;
}
}
二、数组
1、
int[] a = new int[100];
for(int i = 0;i<a.length;i++){
a[i] = i;
}
2、
int[] a = {1,2,3};
3、
int[] a = new int[] {1,2,3};
三、Java内存管理
1、
2、一个数组的玩法
3、对象在内存中运行时二的状态
栈中方法顺序执行,堆中对象属性的临时值可以发生改变,方法区中原始对象的属性值不变 供堆共用。
4、方法中以对象作为参数的方法,传过去的对象参数其实是对象的地址。
四、局部变量和成员变量
1、定义的位置不一样
局部变量:在方法的内部
成员变量:在方法的外部,直接写在类当中
2、默认值不一样
局部变量:没有默认值
成员变量:有默认值
3、内存位置不一样
局部变量:位于栈内存
成员变量:位于堆内存
4、生命周期不一样
局部变量:随着方法进栈而诞生,随着方法出栈而消失
成员变量:随着对象创建而诞生,随着对象被垃圾回收而消失
五、接口
1.接口中的常量、默认方法、静态方法
package com.huan.swagger;
//java8以上版本支持
public interface Interface01 {
//接口中的常量(必须赋值)
public static final int num=10;
int a=1;
//接口方法默认为 public abstract,不写也是
public abstract void a();
//接口的默认方法,实现类可以直接调用,也可以覆盖重写
public default void defaltMethond(){
System.out.println("这是接口的默认方法。。。。。。");
}
//接口的静态方法
public static void methodStatic(){
System.out.println("这是接口的静态方法,,,,,,");
}
}
class A implements Interface01{
@Override
public void a() {
System.out.println("这是A实现类。。。。。。。。");
}
@Override
public void defaltMethond() {
System.out.println("在A实现类覆盖重写接口的默认方法。。。。。。");
}
//调用接口的静态方法
public static void useStatic(){
//直接使用接口名称调用(不能使用实现类的类名调用,因为一个实现类可能会实现多个接口)
Interface01.methodStatic();
}
}
class B implements Interface01{
@Override
public void a() {
System.out.println("这是B实现类。。。。。。。。");
}
}
class client{
public static void main(String[] args) {
Interface01 aImpl =new A();
aImpl.a();
//调用接口的默认方法
aImpl.defaltMethond();
//看一下接口的静态方法有没有效
System.out.println("我看到了------->");
A.useStatic();
Interface01 bImpl=new B();
bImpl.a();
bImpl.defaltMethond();
}
}
六、多态
代码中多态也就是父类引用指向子类对象
package com.huan.swagger;
/**
* @author :huan
* @date :2021/3/24 9:03
* @description:TODO
**/
class Fu{
//变量不会被子类的同名变量覆盖
int num=10;
public void a(){
System.out.println("这是父类的a方法。。。。。");
}
public void b(){
System.out.println("这是父类特有的b方法(不在子类重写)");
}
}
class Zi1 extends Fu{
int num=20;
@Override
public void a(){
System.out.println("覆盖重写父类的a方法。。。。。。");
}
}
public class DuoTai {
public static void main(String[] args) {
Fu zi=new Zi1();
zi.a();
zi.b();
}
}
abstract class Animal{
abstract void eat();
}
class cat extends Animal{
@Override
void eat() {
System.out.println("猫吃东西。。");
}
public String fish(){
return "鱼";
}
}
class dog extends Animal{
@Override
void eat() {
System.out.println("狗吃东西。。");
}
public String gutou(){
return "骨头";
}
}
class client2{
public static void main(String[] args) {
//对象向上转型,就是:父类引用子类对象
Animal cat=new cat();
cat.eat();
Animal dog=new dog();
dog.eat();
//对象向下转型(进行还原操作)
Animal cat2=new cat();
cat cat2s=(cat) cat2;
cat2s.eat();
System.out.println(cat2s.fish());
}
}
七、权限修饰符
八、匿名内部类
package com.huan.swagger;
/**
* @author :huan
* @date :2021/4/5 8:11
* @description:TODO
**/
public class Anonymous_Inner_Class {
public static void main(String[] args) {
AA aa=new AaI();
aa.method();
Aaa aa1=new Aaa();
aa1.methods();
}
}
interface AA{
public void method();
}
class AaI implements AA{
@Override
public void method() {
System.out.println("实现接口的方式。。。。。。。");
}
}
//如果一个实现类只需要在一个地方使用一次,那么可以使用匿名内部类的方法实现,这样可以减少一个实现类的创建
class Aaa{
public void methods(){
AA aa = new AA() {
@Override
public void method() {
System.out.println("以匿名内部类的方式实现。。。。。。。。");
}
};
aa.method();
}
}
九、包装类
Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的。基本类型的数据不具备"对象"的特性(没有成员变量和成员方法可以调用),因此,java为每种数据类型分别设计了对应的类,即包装类。
十、集合
1、迭代器
十一、链表
十二、红黑树
十三、HashSet
重写equals和hashCode方法
public class Blog {
private int id;
private int user_id;
private String content;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Blog blog = (Blog) o;
return id == blog.id &&
user_id == blog.user_id &&
Objects.equals(content, blog.content);
}
@Override
public int hashCode() {
return Objects.hash(id, user_id, content);
}
}
十四、LinkeHashSet
十五、可变参数
Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。
注意:
可变参数必须位于最后一项。 当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持有一个可变参数。因为参数个数不定,所以当其后边还有相同类型参数时,java无法区分传入的参数属于前一个可变参数还是后边的参数,所以只能让可变参数位于最后一项。
可变参数的特点:
(1)、只能出现在参数列表的最后;
(2)、…位于变量类型和变量名之间,前后有无空格都可以;
(3)、调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中一数组的形式访问可变参数。
public class Varable {
public static void main(String [] args){
System.out.println(add(2,3));
System.out.println(add(2,3,5));
}
public static int add(int x,int ...args){
int sum=x;
for(int i=0;i<args.length;i++){
sum+=args[i];
}
return sum;
}
}
十六、Map
1、遍历hashMap
2、Map.Entry
3、hashMap唯一key
4、LinkedHashMap
十七、异常throwable
十八、异常处理
异常处理的几常用个方法
1、多个异常分别处理
2、多个异常一次捕获,多次处理
3、多个异常一次捕获,一次处理
4、finally
5、父类异常怎么样,子类异常就怎么样
6、自定义异常
十九、多线程
1、并发和并行
2、进程
3、线程
通向cpu的路径
4、线程调度
5、创建多线程(继承Thread方式)
public class UseThread {
public static void main(String[] args) {
//3.创建Thread类的子类对象
MyThread myThread = new MyThread();
//4.调用Thread类中的start()方法,开启新的线程,执行run方法
myThread.start();
for (int i = 0; i < 40; i++) {
System.out.println("main:" + i);
}
}
}
//1.创建一个Thread的子类(即实现Thread)
class MyThread extends Thread {
//2.在Thread类的子类中重写Thread类中的run()方法,设置线程任务(开启线程要做什么)
@Override
public void run() {
for (int i = 0; i < 40; i++) {
System.out.println("run:" + i);
}
}
}
随机输出
6、多线程原理
7、获取线程名称
//1.创建一个Thread的子类(即实现Thread)
class MyThread extends Thread {
//2.在Thread类的子类中重写Thread类中的run()方法,设置线程任务(开启线程要做什么)
@Override
public void run() {
System.out.println("线程名称:"+getName());
//获取当前进程的名称
Thread thread = Thread.currentThread();
System.out.println("当前线程名称:"+thread);
for (int i = 0; i < 2; i++) {
System.out.println("run:" + i);
}
}
}
8、sleep
/**
* static void sleep(long millis)
* 使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。
*/
class useSleep{
public static void main(String[] args) {
for (int i = 0; i < 60; i++) {
if(i==0){
System.out.print(i+1);
System.out.print("秒");
}else {
System.out.print("、");
System.out.print(i+1);
System.out.print("秒");
}
try {
//睡眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
9、创建多线程(实现Runnable方式)
Java不支持多继承,支持多实现,而且把设置线程任务和开启新线程进行了分离(解耦),所以这种创建多线程的方法好一点
class UseRunnableClient{
public static void main(String[] args) {
//3.创建一个Runnable接口的实现类对象
UseRunnable useRunnable=new UseRunnable();
//4.创建Thread类对象,构造方法中传递Runnable接口的实现类对象
Thread thread=new Thread(useRunnable);
//5.调用Thread类中的start方法,开启新的线程执行run方法
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println(i+"-----------------"+Thread.currentThread().getName());
}
}
}
//1.创建一个Runnable接口实现类
class UseRunnable implements Runnable{
//2.在实现类中重写Runnable接口的run()方法,设置线程任务
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i+"-----------------"+Thread.currentThread().getName());
}
}
}
10、线程安全
①、同步代码块
②、同步方法
③、Lock锁
private Lock lock = new ReentrantLock();
//上锁
lock.lock();
//释放锁
lock.unlock();
class MyCondition implements Runnable{
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void run() {
try {
//上锁
lock.lock();
System.out.println("当前线程名:"+Thread.currentThread().getName()+" 开始等待时间:"+System.currentTimeMillis());
//线程等待
condition.await();
System.out.println("我陷入了等待...");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//释放锁
lock.unlock();
System.out.println("锁释放了!");
}
}
}
11、等待唤醒
包子案例
package com.huan.swagger.thread;
/**
* @author :huan
* @date :2021/4/10 9:46
* @description:TODO
**/
public class UseAwaken {
public static void main(String[] args) {
//创建包子对象
Bread bread=new Bread();
//创建包子铺线程,开启,生产包子
new BreadStore(bread).start();
//创建吃货线程,开启,吃包子
new Foodie(bread).start();
}
}
//包子
class Bread{
//皮
String skin;
//馅
String fillings;
//包子的状态(有true,没有false)
boolean flag=false;
}
//包子铺
class BreadStore extends Thread{
//1.创建一个包子变量
private Bread bread;
//2.使用带参数的构造方法,为这个包子变量赋值
public BreadStore(Bread bread) {
this.bread = bread;
}
//设置线程任务(run):生产包子
@Override
public void run() {
//定义一个变量
int count=0;
//让包子铺一直生产包子
while (true){
//必须同时同步技术保证两个线程只能有一个在执行
synchronized (bread){
//对包子的状态进行判断
if (bread.flag==true){
//(有面包)包子铺调用wait方法进入等待状态
try {
bread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//被唤醒之后执行(wait后面的代码),包子铺生产包子
//交替生产两种包子
if (count%2==0){
//生产薄皮三鲜馅包子
bread.skin="薄皮";
bread.fillings="三鲜馅";
}else {
//生产冰皮牛肉馅包子
bread.skin="冰皮";
bread.fillings="牛肉馅";
}
count++;
System.out.println("包子铺正在生产"+bread.skin+bread.fillings+"包子。");
//生产包子需要3秒(然线程睡3秒)
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//包子铺生产好包子,修改包子的状态为true
bread.flag=true;
//唤醒吃货线程,让吃货线程吃包子
bread.notify();
System.out.println("包子铺生产好了"+bread.skin+bread.fillings+"包子,吃货可以开始吃了。");
}
}
}
}
//吃货
class Foodie extends Thread{
//1.创建一个包子变量
private Bread bread;
//2.使用带参数的构造方法,为这个包子变量赋值
public Foodie(Bread bread) {
this.bread = bread;
}
//设置线程任务(run):吃包子
@Override
public void run() {
//让吃货一直吃包子
while (true){
//必须同时同步技术保证两个线程只能有一个在执行
synchronized (bread){
//对包子的状态进行判断
if (bread.flag==false){
//(没有面包)吃货调用wait方法进入等待状态
try {
bread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//被唤醒之后执行(wait后面的代码),吃包子
System.out.println("吃货正在吃"+bread.skin+bread.fillings+"包子。");
//吃完包子,修改包子状态为false没有
bread.flag=false;
//唤醒包子铺线程,让包子铺线程生产包子
bread.notify();
System.out.println("吃货吃完了"+bread.skin+bread.fillings+"包子,包子铺开始生产包子。");
System.out.println("-----------------------------------------------------");
}
}
}
}
12、线程池
线程池使用
二十、Lambda表达式
1、无参无返回值
/**
* @author :huan
* @date :2021/4/10 11:21
* @description:TODO
**/
public class UseLambda {
public static void main(String[] args) {
//调用invokeCook方法,参数是Cook接口,传递Cook接口的匿名内部类
invokeCook(new Cook() {
@Override
public void makeFood() {
System.out.println("吃饭了------------------------");
}
});
//使用Lambda表达式调用
invokeCook(()->{
System.out.println("LambDa吃饭了+++++++++++++++++++++++");
});
}
//定义一个方法,参数传递Cook接口,方法内容是调用Cook接口里面的makeFood方法
public static void invokeCook(Cook cook){
cook.makeFood();
}
}
//第一个Cook接口,内容包含唯一的抽象方法makeFood
interface Cook{
//无参数无返回值的方法
public abstract void makeFood();
}