JAVA------基础篇

时间:2024-05-08 08:56:44

java基础

1.JDK

JDK :java development kit
JRE:java runtime environment
JDK包含JRE
java跨平台:因为java程序运行依赖虚拟机,虚拟机需要有对应操作系统的版本,而jre中有虚拟机。
当你想要在Linux系统下运行,则需要安装对应的虚拟机,及对应的jdk版本,而对应的jdk版本中的jre有对应的虚拟机

2.标识符:我们自己定义的名字

类名:不能以数字开头,只能有_ $ 字母 数字
类方法:前面小写,第二个单词大写。

3.常量:不能变的值。system.out.println(100);

4.变量:指在计算机内存中,可以随时改变的量。int i = 2; system.out.println(i);

【注意:八个比特等于一个字节】

5.算术运算符:int a=3; int b = a++ + 10;a=4,b=13

6.数据类型:范围 byte<short<int<long<float<double

7.方法:

注意点:
1.方法不能定义在另一个方法里面
2.调用方法时,返回值是void,不能写在输出语句中
3.方法重载:
1.参数列表必须不同
2.重载和参数变量名无关
3.重载和返回值类型无关
4.重载和修饰符无关
总结:重载只看方法名和参数列表

在这里插入图片描述

当把方法中的void改为int并且加个返回值return ;则需要在main方法中调用change方法的同时需要给其赋值。如:a=change(a,b);否则还是会出现上面这种a,b不变的情况。

在这里插入图片描述

为什么这个方法跟上面差不多,只是把参数换了个引用类型参数,结果就能成功赋值?

因为int[] arr = [1,2,3,4];在堆上开辟了一个容器,且有个地址返回给int[] arr,当你调用change,将arr[2]赋值为100,则方法会根据地址去对对应的arr[2]进行赋值,方法结束时,change退出方法栈,但是此时值以及改好。
ArrayList<>:<>里面存放的是引用数据类型。如:int的引用数据类型是integer(四类八种中有两个基本数据类型和引用数据类型不同,一个是int(integer),一个是char(character))

=============================================================

transient:在不需要序列化的属性前面加个transient,则序列化对象的时候,这个属性就不会被序列化。

序列化

package com.li.demo01;

import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;

public class iterator {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        File file = new File("xxx.txt");
        FileOutputStream fos = new FileOutputStream(file);
        ObjectOutputStream op = new ObjectOutputStream(fos);
        User user = new User(1,2);
        op.writeObject(user);
        op.flush();
        op.close();

        System.out.println(user);

        System.out.println("=========================================");

        FileInputStream fls = new FileInputStream(file);
        ObjectInputStream oi = new ObjectInputStream(fls);
        User user1 = (User) oi.readObject();
        System.out.println(user1);

    }
}

实体类
package com.li.demo01;

import java.io.Serializable;

public class User implements Serializable {
    private static final long serialVersionUID = -134246534L;
    private int id;
    transient int age;

    public User() {
    }

    public User(int id, int age) {
        this.id = id;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", age=" + age +
                '}';
    }
}

输出结果

User{id=1, age=2}
=========================================
User{id=1, age=0}

进程已结束,退出代码 0

面向对象

1.成员变量与局部变量的不同
局部变量没有赋值不能输出,成员变量可以。

public class demo7 {

	static int x;
	
	public void run(){
		int i;
		System.out.println(i);//注意这里的i会报错,因为i为局部变量,局部变量没有赋值,是不能进行输出。
	}
	public static void main(String[] args) {
		System.out.println(x);
	}

}

内存位置不同

在这里插入图片描述
在这里插入图片描述

生命周期不同
成员变量,跟随对象,在堆中存储,内存等待JVM清理,生命周期较长
局部变量,跟随方法,方法出栈,生命周期相对较短。

注意:重点需要会掌握如何区*部还是成员变量即可。

面向对象方法参数:基本数据类型和引用数据类型
基本数据类型

在这里插入图片描述

引用数据类型

在这里插入图片描述

private修饰词

只能修饰成员变量,不能修饰局部变量
总结:类中不需要对外提供的内容都私有化,包括属性的方法。
以后再描述事物,属性都私有化,并提供setXXX getXXX方法对其进行访问。
注意:私有仅仅是封装的体现形式而已。

this关键字

区分成员变量和局部变量的同名的情况
方法中访问成员变量,写this.
凡是写this. 的都是访问成员变量。

在这里插入图片描述

this的使用年纪的比较

在这里插入图片描述

extend继承

在这里插入图片描述
在这里插入图片描述

当子父类中出现了同名成员变量时,在子类中若要访问父类中的成员变量,必须使用关键字super来完成。

this. 调用自己本类成员

super. 调用的自己的父类成员

重写:子类和父类方法一样(参数名一样)的时候。(注意区别于重载,重载是参数不一样)

子类重写父类的方法,保证子类方法的权限大于或者等于父类方法权限

四大权限 public protected default private (方法默认是default权限)

在这里插入图片描述
在这里插入图片描述

abstract

在这里插入图片描述

抽象类,不能实例化对象,不能new对象。

不能创建对象的原因:如果你真的实例化对象了,对象.调用抽象方法,但是抽象方法中没有方法体,根本不能运行。
抽象类强制它的子类执行抽象方法,重写父类的方法,就不需要写抽象修饰词,加上主体即可。

在这里插入图片描述

2.4抽象类的细节问题:

1、抽象类一定是个父类?
是的,因为不断抽取而来的。
2、抽象类中是否可以不定义抽象方法。
是可以的,那这个抽象类的存在到底有什么意义呢?不让该类创建对象,方法可以直接让子类去使用

3、抽象关键字abstract不可以和哪些关键字共存?
1、private:私有的方法子类是无法继承到的,也不存在覆盖,而abstract和private一起使用修饰方法,abstract既要子类去实现这个方法,而private修饰子类根本无法得到父类这个方法。互相矛盾。
2、final,暂时不关注,后面学
3、static,暂时不关注,后面学

接口

定义抽象方法:固定格式 public abstract 返回值类型 方法名字(参数列表);

修饰符 public 写,或者不写都是public。但是别的地方不写则是default。
接口中定义变量:固定格式:public static final 数据类型 变量名 = 值;(并且因为,static,所以它可以直接通过接口的名字直接调用它)我们不写前面这些修饰词,不代表没有,接口会自动写进去。

如:

在这里插入图片描述
在这里插入图片描述

注意点:接口和继承中当你实现接口,或者继承类时强制要求你写出方法是因为其中的abstract的原因。

继承父类,当父类中方法有abstract,则继承时就需要重写。

类对接口方法的实现的时候,不管接口中是否有写public abstract都需要加上public

实现多个接口

在这里插入图片描述

实现多个接口需要避免这个情况

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

抽象类和接口的区别:

抽象类是这个体系应该有的东西,而接口是体系中额外的扩展功能在这里插入图片描述

interface 缉毒{
	public abstract void 缉毒();
}
//定义犬科的这个提醒的共性功能
abstract class 犬科{
public abstract void 吃饭();
public abstract void 吼叫();
}
// 缉毒犬属于犬科一种,让其继承犬科,获取的犬科的特性,
//由于缉毒犬具有缉毒功能,那么它只要实现缉毒接口即可,这样即保证缉毒犬具备犬科的特性,也拥有了缉毒的功能
class 缉毒犬 extends 犬科 implements 缉毒{

	public void 缉毒() {
	}
	void 吃饭() {
	}
	void 吼叫() {
	}
}
class 缉毒猪 implements 缉毒{
	public void 缉毒() {
	}
}

多态

多态体现为父类引用变量可以指向子类对象。
多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态。
在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。

如:接口 变量 = new 实现类():

********

父类

public class Animal {//父类
	
	static int cons = 1;
	
	int val = 1;
	
	final int fin = 1;
	
	public void eat() {
		System.out.println("animal eat");
	}
	
	
	static void eat2() {
		System.out.println("animal eat2");
	}
}

子类

public class Cat extends Animal{
	
	static int cons = 2;
	
	int val = 2;
	
	final int fin = 2;
	
	@Override
	public void eat() {
		System.out.println("cat eat");
	}
	
	static void eat2() {
		System.out.println("cat eat2");
	}
		
}

测试类(调用父子类中一样的方法,则输出结果是子类的方法,要想调用父类的方法,需要在父类中加上static。
调用父子类中的成员,默认输出结果是父类的成员变量。原因【编译、运行都是跟着父类走】且通过多态调用的成员变量,无论是普通类型,静态类型,常量类型仍是父类的成员变量,因为成员变量不存在override(覆盖)问题

public static void main(String[] args) {
		Animal a = new Cat();//父类引用
		
		System.out.println(a.val);//成员变量
		System.out.println(a.cons);//静态变量
		System.out.println(a.fin);//常量
		
		a.eat();//成员方法
		a.eat2();//静态方法
		
	}

输出结果

1
1
1
cat eat
animal eat2

在这里插入图片描述

instanceof判断变量p是Student还是Teacher(前提:两个类都需要继承Person)。

格式:引用变量 instanceof 类名

boolean a = p instanceof Student;

Person p = new Stduent();Person p = new Teacher();【Teacher 向上转型(优点:可以调用子类和父类的共有内容。缺点:不能调用子类中特有的内容。如何解决缺点:可以加强转。如:Teacher t = (Teacher)p;
)】

构造方法的作用:当我们new对象的时候自动赋值上去。以往都是new完对象再赋值。

构造方法的定义格式

权限 方法名(参数列表){
}
方法的名字,必须和类的名字完全一致
构造方法不允许写返回值类型,void也不能写。

当你new对象的时候,构造方法就执行,而且仅执行一次

![在这里插入图片描述](https://img-blog.****img.cn/20210616092445352.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1Rocml2ZV9MQ1g=,size_16,co

this在构造方法之间的调用:

this():减轻了无参构造的代码量。
package cn.itcast.demo03;
/*
 *   this可以在构造方法之间进行调用
 *   this.的方式,区*部变量和成员变量同名情况
 *   this在构造方法之间的调用,语法 this()
 */
public class Person {
	private String name;
	private int age;
	
	public Person(){
		//调用了有参数的构造方法
		//参数李四,20传递给了变量name,age
		this("李四",20);//调用this()需要让它再构造方法的第一行
	}
	/*
	 *  构造方法,传递String,int
	 *  在创建对象的同时为成员变量赋值
	 */
	public Person(String name,int age){
		this.name = name;
		this.age = 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;
	}
	
	
}

package cn.itcast.demo03;

public class Test {
	public static void main(String[] args) {
		//创建Person的对象,调用的是空参数的构造方法
		//运行的结果 null 0
		Person p = new Person();
		
		System.out.println(p.getName());
		System.out.println(p.getAge());
	}
}

内存图
在这里插入图片描述

super关键字

父类
在这里插入图片描述

子类
在这里插入图片描述
测试类
在这里插入图片描述

在这里插入图片描述

我们发现,当我们new一个子对象的时候,输出父类中无参构造的值。说明我们子类中有隐藏的

public zi(){
		super();
	}

这段代码

须知:子类中的构造方法是用来调用父类方法的。(super含义:标明了父类文件所在的内存区域)

内存图
在这里插入图片描述

注意点:子类中所有的构造方法,无论重载多少个,第一行必须是super()

如:
父类

/*
 *   手动写一个父类Person类的构造方法,加入int类型参数
 *   保存,子类就报错
 */
public class Person {
	public Person(int a){
	
	}
	
	public Person(double d){
		
	}
}

子类

/*
 *  子类构造方法的报错原因: 找不到父类的空参数构造器
 *  子类中,没有手写构造,编译器添加默认的空参数
 *  public Student(){
 *     super();
 *  }
 *  编译成功,必须手动编写构造方法,请你在super中加入参数
 *  
 *  注意: 子类中所有的构造方法,无论重载多少个,第一行必须是super()
 *  如果父类有多个构造方法,子类任意调用一个就可以
 *  super()语句必须是构造方法第一行代码
 */
public class Student extends Person{
	public Student(){
		
		super(0.1);
	
	}
	
	public Student(String s){
		super(1);
	}
}

案例:
父类

public class Person extends Object{

	public Person(int a) {
	
	}
	
	
}

子类

/*
 	构造方法第一行,写this()还是super()
 	不能同时存在,任选其一,保证子类的所有构造方法调用到父类的构造方法即可
 	
 	小结论: 无论如何,子类的所有构造方法,直接,间接必须调用到父类构造方法
 	子类的构造方法,什么都不写,默认的构造方法第一行 super();
 */
public class Student extends Person{
	public Student(){
		//调用的是自己的构造方法
		//间接形式调用到了父类的构造方法
		this("abc");
	}
	
	public Student(String s){
		super(1);
	}
}

测试类

public class Test {
	public static void main(String[] args) {
		new Student();
	}
}

final修饰引用变量问题

变量,保存内存地址,终身不变

final Zi z2 = new Zi();
z2 = new Zi();

* final修饰成员变量

  • 成员变量,在堆内存,具有默认值
  • final修饰的成员变量,固定的不是内存的默认值
  • 固定的是,成员变量的手动赋值,绝对不是内存的默认
  • 成员变量的赋值,2种实现方式,一种是定义的时候,直接=赋值
  • 另一种赋值方式,采用构造方法赋值
  • 保证: 被final修饰的成员变量,只能被赋值一次
  • 成员变量,需要在创建对象前赋值,否则报错
  • 构造方法,是创建对象中的事情,可以为成员变量赋值
  • setXXX方法,创建对象之后的时候,不能为final修饰的成员赋值

static

在这里插入图片描述
在这里插入图片描述

静态不能写this,不能写super。因为this表示本类的对象引用,而静态优先于对象

当我们的方法不是静态方法的时候,我们就需要去先new一个对象,才能调用那个方法。解决:那个方法为静态则可以不用new直接调用。在这里插入图片描述

在这里插入图片描述

内部类

调用规则:内部类,可以使用外部类成员,包括私有外部类要使用内部类的成员,必须建立内部类对象。

在这里插入图片描述
在这里插入图片描述

匿名内部类

定义实现类,重写方法,创建实现类对象,一步搞定

格式: new 接口或者父类(){

重写抽象方法

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

导包

classpath是帮助虚拟机找到jar包的位置
在命令窗口也可配置 如:set classpath=d:\method.jar
在eclipse中直接在项目点击右键创建一个folder为lib,再把要导入的jar包放进去即可。

String

在这里插入图片描述

Calendar

/*
	 *  闰年计算
	 *  2000 3000
	 *  高级的算法: 日历设置到指定年份的3月1日,add向前偏移1天,获取天数,29闰年
	 */
	public static void function_1(){
		Calendar c = Calendar.getInstance();
		//将日历,设置到指定年的3月1日
		c.set(2088, 2, 1);
		//日历add方法,向前偏移1天
		c.add(Calendar.DAY_OF_MONTH, -1);
		//get方法获取天数
		int day = c.get(Calendar.DAY_OF_MONTH);
		System.out.println(day);
	}

自动装拆箱

/*
 *   JDK1.5后出现的特性,自动装箱和自动拆箱
 *   自动装箱: 基本数据类型,直接变成对象
 *   自动拆箱: 对象中的数据变回基本数据类型
 */
public class IntegerDemo2 {
	public static void main(String[] args) {
		function_2();
	}
	/*
	 *  关于自动装箱和拆箱一些题目
	 */
	public static void function_2(){
		Integer i = new Integer(1);
		Integer j = new Integer(1);
		System.out.println(i==j);// false 对象地址
		System.out.println(i.equals(j));// true  继承Object重写equals,比较的对象数据
		
		System.out.println("===================");
		
		Integer a = 500;
		Integer b = 500;
		System.out.println(a==b);//false
		System.out.println(a.equals(b));//true
		
		System.out.println("===================");
		
		
		//数据在byte范围内,JVM不会从新new对象
		Integer aa = 127; // Integer aa = new Integer(127)
		Integer bb = 127; // Integer bb = aa;
		System.out.println(aa==bb); //true
		System.out.println(aa.equals(bb));//true
	}
	
	
	//自动装箱和拆箱弊端,可能出现空指针异常
	publi