LOADING...

加载过慢请开启缓存(浏览器默认开启)

loading

Java基础+对象和类+变量类型+修饰符+运算符+各种类+数组

2022/4/28 后端

Java基础语法

  • 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、吃、叫等。

  • :类[class]是一个模板,它描述一类对象的行为和状态

  • 方法:方法就是行为,一个类可以有很多方法。

  • 实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。

  • 编写java时应注意几点:

    大小写敏感

    类名:对所有类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写:MyFirstJavaClass

    方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。

    源文件名:源文件名必须和类名相同。当保存文件时,你应该使用类名作为文件名保存(切记Java是大小写敏感的),文件名的后缀为java。

    主方法入口:所有的Java程序由public static void main(String[] args)方法开始执行。

  • Java变量:局部变量、类变量(静态[static]变量)、成员变量(非静态变量)

  • 方法:访问权限符 返回值 方法名(参数列表){ 方法体 }

    ​ public void method() {sout(“Hello”);}

    interface:接口,一种抽象的类型,仅有方法和常量的定义

    implements:表示一个类实现了接口

    abstract:抽象方法,抽象类的修饰符

    extends:表示一个类是另一个类的子类(继承)

    private:表示私有字段,或者方法等,只能从类内部访问

    protected:表示字段只能通过类或者子类访问,子类或者在同一个包内的其他类

    public:表示共有属性或方法

    static:表示在类级别定义,所有实例共享的

    throw:抛出异常

    throws:定义方法可能抛出的异常

  • 继承:在Java中,一个类可以由其他类派生,如果你要创建一个类,而且已经存在一个类具有你所需要的属性或方法,那么你可以将新创建的类继承该类,利用继承的方法,可以重用已存在类的方法和属性,而不用重写这些代码。被继承的类称为超类(super class),派生类称为子类(subclass)

  • 接口:在Java中,接口可理解为对象间互相通信的协议。接口在继承中扮演着很重要的角色。接口值定义派生要用到的方法,但是方法的具体实现完全取决于派生类。

Java对象和类

  • Java中的类和方法[方法就是行为,一个类可以有很多方法]
public class Dog{
    String breed;
    int age;
    String color;
    
    void barking(){
        
    }
    void hungry(){
        
    }
    void sleeping(){
        
    }
}

一个类可以拥有多个方法,在上面的例子中:barking()、hungry()、sleeping() 都是Dog类的方法


构造方法

每个类都有构造方法,不主动创建编译器将会为该类提供一个默认的构造方法,在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。

public class Puppy{
    public Puppy(){
        
    }
    public Puppy(String name){
        //这个构造器仅有一个参数:name
    }
}

创建对象

对象是根据类创建的。在java中,使用关键字new来创建一个新的对象。

  • 声明:声明一个对象,包括对象名称和对象类型
  • 实例化:使用关键字new来创建一个对象
  • 初始化:使用new创建对象时,会调用构造方法初始化对象
public class Puppy{
    public Puppy(String name){
        //这个构造器仅有一个参数:name
        sout("Puppy Name is :" + name);
    }
    public static void main(String[] args){
        //下面的语句将创建一个Puppy对象
        Puppy myPuppy = new Puppy("tommy");
    }
}

打印出下面结果:
Puppy Name is : tommy

访问实例变量和方法

//实例化对象
ObjectReference = new Constructor();
//访问其中的变量
ObjectReference.variableName;
//访问类中的方法
ObjectReference.MethodName();

实例

访问实例变量和调用成员方法:

public class Puppy{
    int puppyAge;
    public Puppy(String name){
        sout("Passed Name is :" + name);
    }
    public void setAge(int age){
        puppyAge = age;
    }
    public int getAge(){
        sout("Puppy's age is :" + puppyAge);
        return puppyAge;
    }
    
    public static void main(String[] args){
        //创建对象
        Puppy myPuppy = new Puppy("tommy");
        //通过方法来设定age
        myPuppy.setAge(2);
        //调用另一个方法获取age
        myPuppy.getAge();
        //也可以这样访问成员变量
        sout("Variable Value :" + myPuppy.puppyAge);
    }
}

输出结果:
Passed Name is :tommy
   's age is :2
PuppyVariable Value :2

源文件声明规则

  • 一个源文件中只能有一个public类

  • 一个源文件可以有多个非public类

  • 源文件的名称应该和public类的类名保持一致。例如:源文件中public类的类名是Employee,那么源文件应该命名为Employee.java

  • 特殊的转义字符序列

\n 换行
\r 回车
\f 换页符
\b 退格
\0 空字符
\s 字符串
\t 制表符

Java变量类型

一个类可以包含以下类型变量:

  • 局部变量:在方法、构造方法或者语句块中定义的变量称之为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。局部变量是在栈上分配的。局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用(类方法中的变量)(局部变量的作用域仅限制在被创造的方法中)
  • 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。(独立于方法之外的变量,不过没有static修饰)
  • 类变量:类变量(静态变量)也声明在类中,方法体之外,但必须声明为static类型。无论一个类创建了多少个对象,类只拥有类变量的一份拷贝。静态变量除了被声明为常量外很少使用,常量是指声明为public/private,final和static类型的变量,常量初始化后不能改变。静态变量存储在静态存储区,经常被声明为常量,很少单独使用static声明变量。类变量被声明为public static final 类型时,类变量名称必须使用大写字母,如果静态变量不是public和final类型,其命名方式与实例变量以及局部变量的命名方式一致。(独立于方法之外的变量,用static修饰)

然后是static

static在java中表示静态

但是这个静态又是什么意思呢?

最开始接触static的时候看书上的概念根本没弄懂!

接触有一段时间java了,在这里面要总结一下我对static的理解:

(概念)static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。

这句话是说,你会用到static修饰一些个变量、方法、方法块什么的,这是你用到static的地方;“但是,java中没有全局变量的概念”,怎么理解这句话?你时刻要记住java是一个面向对象的语言,万事万物皆对象,无论你做什么都需要创建一个对象,然后再调用这个对象的方法,java怎么能允许存在一个在全局都通用的“全局变量”的概念存在呢?所以java中压根就没有所谓的“全局变量”,但是没有这个概念,不代表你不可以实现这个功能,java存在的目的就是让人们使用它去达到人们想要的效果,所以static value就可以达到全局变量的作用,所以,你现在应该可以理解下面这句话了吧。

(概念)用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象市,不生成static变量的副本,而是类的所有实例共享同一个static变量。

现在进一步理解下面两段概念:

(概念)只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。

import java.io.*;
public class Employee{
    //salary是静态的私有变量
    private static double salary;
    //DEPARTMENT是一个常量
    public static final String DEPARTMENT = "Development ";
    public static void main(String args[]){
        salary = 1000;
        sout(DEPARTMENT + "average salary:" + salary);
    }
}
输出结果:
Develment average salary:1000
public class Variable{
    static int allClicks = 0;    //类变量
    String str = "hello world"; //实例变量
    public void method(){
        int i = 0; //局部变量
    }
}

实例:

import java.io.*;
public class Employee{
    //这个成员变量对子类可见
    public String name;
    //私有变量,仅在该类可见
    private double salary;
    //在构造器中对name赋值
    public Employee(String empName){
        name = empName;
    }
    //设定salary的值
    public void setSalary(double empSal){
        salary = empSal;
    }
    //打印信息
    public void printEmp(){
        sout("name :" + name);
        sout("salary :" + salary);
}
    public ststic void main(String args[]){
        Employee empOne = new Employee("Ransika");
        empOne.setSalary(1000);
        empOne.printEmp();
    }
}
输出结果:
name : Ransika
salary :1000.0

Java修饰符

访问控制修饰符

  • default 默认的:在同一包内可见,不使用任何修饰符
  • private 私有的:在同一类内可见。私有访问修饰符是最严格的访问级别,所以被声明为private的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为private。private访问修饰符的作用主要用来隐藏类的实现细节和保护类的数据
public class Logger{
    private String format;
    public String getFormat(){
        return this.format;
    }
    public void setFormat(String format){
        this.format = format;
    }
}

实例中,Logger类中的format变量为私有变量,所以其他类不能直接得到和设置该变量的值。为了使其他类能够操作该变量,定义了两个public方法:getFormat() (返回format的值) 和 setFormat(String) (设置format的值)

  • public 公有的:对所有类可见,被声明public的类、方法、构造方法和接口能够被任何其他类访问。如果几个互相访问的public类分布在不同的包中,则需要导入相应public类所在的包。由于类的继承性,类所有的共有方法和变量都能被子类继承
public static void main(String[] arguments){
    //...(公有访问控制)
}

Java程序的main()方法必须设置成共有的,否则,不能运行该类

  • proteed 受保护的:对同一包内的类和所有子类可见

被声明为protected的变量、方法和构造器能被同一个包中的任何其他类访问,也能够被不同包中的子类访问。protected访问修饰符不能修饰类和接口,方法和成员变量能够声明protected,但是接口的成员变量和成员方法不能声明为protected,子类能访问protected修饰符声明的方法和变量,这样就能保护不相关的类使用这些方法和变量。

下面的父类使用了protected访问修饰符,子类重载了父类的openSpeaker()方法。

class AudioPlayer{
    protected boolean openSpeaker(Speaker sp){
        //实现细节
    }
}
class StreamingAudioPlayer{
    boolean openSpeaker(Speaker sp){
        //实现细节
    }
}

如果把openSpeaker()方法声明为private,那么除了AudioPlayer之外的类将不能访问该方法

如果把openSpeaker()方法声明为public,那么所有的类都能够访问该方法

如果我们只想让该方法对其所在的类的子类可见,则将该方法声明为protected

  • 访问控制和继承规则:
    • 父类中声明为public的方法在子类中也必须为public
    • 父类中声明为protected的方法在子类中要么声明为protected,要么声明为public,不能声明为private
    • 父类中声明为private的方法,不能够被继承

控制非访问修饰符

  • static 修饰符:用来创建类方法和类变量

    • 静态变量:static关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。静态变量也成为类变量。局部变量不能被声明为static变量
    • 静态方法:static关键词用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据

    对类变量和方法的访问可以直接使用classname.variablename 和 classname.methodname的方式访问

    下面为static修饰符用来创建类方法和类变量

public class InstanceCounter{
    private static int numInstances = 0;
    protected static int getCount(){
        return numInstances;
    }
    
    private static void addInstance(){
        numInstances++;
    }
    
    InstanceCounter(){
        InstanceCounter.addInstance();
    }
    
    public static void main(String[] arguments){
        sout("Starting with" + InstanceCounter.getCount() + " instances");
        for(int i = 0; i < 500; ++i){
            new InstanceCounter();
        }
        sout("Created " + InstanceCounter.getCount() + "instances");
    }
}
输出结果:
Started with 0 instances
Created 500 instances
  • final 修饰符:用来修饰类、方法和变量,final修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的

    • final变量:能被显示地初始化并且只能初始化一次。被声明为final的对象的引用不能指向不同的对象。但是final对象里的数据可以被改变,也就是说final对象的引用不能改变,但是里面的值可以改变。final修饰符通常和static修饰符一起使用来创建类常量。
    public class Test{
        final int value = 10;
        //下面是声明常量的实例
        public static final int BOXWIDTH = 6;
        static final String TITLE = "Manger";
        
        public void changeValue(){
            value = 12; //将输出一个错误
        }
    }
    
    • final方法: 类中的final方法可以被子类继承,但是不能被子类修改。声明final方法的主要目的是防止该方法的内容被修改

    如图为final修饰符声明方法

    public class Test{
        public final void changeName(){
            //方法体
        }
    }
    
    • final类: final类不能被继承,没有类能够继承final类的任何特性
    public final class Test{
        //类体
    }
    
  • abstrat 修饰符:用来创建抽象类和抽象方法

    • 抽象类:抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。一个类不能同时被abstract和final修饰,如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则编译错误。抽象类包含抽象方法和非抽象方法。
    • 抽象方法:是一种没有任何实现的方法,该方法的具体实现由子类提供,抽象方法不能被声明成final和static。任何继承抽象类的子类必须实现父类的所有抽象方法,除非子类也是抽象类。抽象类可以不包含抽象方法。
    abstract class Caraven{
        private double price;
        private String model;
        private String year;
        public abstract void goFast(); //抽象方法
        public abstract void changeColor();
    }
    
    public abstract class SuperClass{
        abstract void m(); //抽象方法
    }
    class SubClass extends SuperClass{
        //实现抽象方法
        void m(){
            // ......
        }
    }
    
  • synchronized和volatile 修饰符: 主要用于线程的编程 (这里不具体研究)


Java运算符

位运算

假设a=60,b=13;

    a = 0011 1100
    b = 0000 1101
----------------------
a & b = 0000 1100
a | b = 0011 1101
a ^ b = 0011 0001
~ a   = 1100 0011

instanceof 运算符

该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型 或 接口类型)

instanof运算符使用格式如下:

(Object reference variable)instanceof(class/interface type)

如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真

String name = "James";
boolean result = name instanceof String;
//由于name是String类型,所以返回真
class Vehicle{}
public class Car extends Vehicle{
    public static void main(String args[]){
        Vehicle a = new Car();
        boolean result = a instanceof Car;
        sout(result);
    }
}
输出结果:
true

continue关键字 + 增强型for循环

continue适用于任何循环控制结构中,作用是让程序立刻跳转到下一次循环的迭代

for循环中,continue语句使程序立刻跳转到更新语句

while或者do…while循环中,程序立刻跳转到布尔表达式的判断语句

public class Test{
    public static void main(String args[]){
        int {} numbers = {10, 20, 30, 40, 50};
        for(int x : numbers){
            if(x == 30){
                continue;
            }
            sout(x);
            sout("\n");
        }
    }
}
输出结果:
10
20
40
50

Java Number类、Math类、Character类

Number包装类型

byte -> Byte        int -> Integer        short -> Short        long -> Long
double -> Double    float -> Float        boolean -> Boolean    char -> Character

包装类型都是用final声明了,不可能被继承重写。在实际情况中编译器会自动的将基本类型数据装箱成对象类型,或者将对象类型拆箱成基本类型

public static void main(String[] args){
    int num1 = 1;
    //将基本类型数据装箱成对象包装类型
    Integer num2 = num1;
    Integer num3 = 3;
    //将对象数据类拆箱
    int num4 = num3;
}

下面是一个装箱与拆箱的例子:

public class Test{
    public static void main(String args[]){
        Integer x = 5;
        x = x + 10;
        sout(x);
    }
}
输出结果:
15

Math类型

Java的Math包含了用于执行基本数学运算的属性和方法:初等指数、对数、平方根和三角函数

Math的方法都被定义为static形式,通过Math类可以在主函数中直接调用 sout(“90°正弦值:” + Math.sin(Math.PI / 2));

下表是常用的Number类和Math类的方法:

序号 方法与描述
1 xxxValue():将number对象转换为xxx数据类型的值并返回
2 compareTo():将number对象与参数比较
3 equals():判断number对象是否与参数相等
4 valueOf():返回一个Integer对象指定的内置数据类型
5 toString():以字符串形式返回值
6 parseInt():将字符串解析为int类型
7 abs():返回参数的绝对值
8 floor():返回小于等于给定参数的最大整数
9 round():返回一个最接近的int、long型值
10 exp():返回自然数底数e的参数次方
11 log():返回参数的自然数底数的对数值
12 pow():返回第一个参数的第二个参数次方
13 sqrt():求参数的算术平方个
14 random():返回一个随机数

Character类

使用字符时,我们通常使用的是内置数据类型char

  • Character类的用法:可以使用Character的构造方法创建一个Character类对象
Character ch = new Character('a');
----------------------------------
Character ch = 'a';
char c = test('x');
isLetter()是否是一个字母        isDigit()是否是一个数字字符
isUpperCase()是否是大写字母    isLowCase()是否是小写字母
toUpperCase()指定字母的大写形式 isLowerCase()指定字母的小写形式
toString()返回字符的字符串形式,字符串的长度仅为1

注意:String类是不可改变的,所以你一旦创建了String对象,那它的值就无法改变了。

可以通过StringBuffer类 和 StringBuilder类(能够被多次的修改,并且不产生新的未使用对象)

public class Test{
    public static void main(String args[]){
        StringBuffer sBuffer = new StringBuffer("test");
        sBuffer.append("String Buffer");
        sout(sBuffer);
    }
}
输出结果:
test String Buffer
public StringBuffer append(String s) 将指定的字符串追加到此字符序列
public StringBuffer reverse() 将此字符序列用其反转形式取代
public delete(int start, int end) 移除此序列的子字符串中的字符
public insert(int offset, int i) 将int参数的字符串表示形式插入此序列中
replace(int start, int end, String str) 使用给定String中的字符替换此序列的子字符串中的字符

Java数组

声明数组变量

dataType[] arrayRefVar;
double[] myList;

创建数组

Java语言使用new操作符来创建数组

arrayRefVar = new dataType[arraySize];
此语法语句做了两件事:
    ①:使用dataType[arraySize]创建了一个数组
    ②:把新创建的数组的应用赋值给变量arrayRefVar

所以数组的变量声明创建数组可以用一条语句完成

dataType[] arrayRefVar = new dataType[arraySize]

数组的元素时通过索引来访问的,数组索引从0开始,所以索引值从0到arrayRefVar.length-1

定义一个int类型的数组

public class ArrayDemo{
    public static void main(String args[]){
        int data[] = new int[3]; //开辟了一个长度为3的数组
        //在数组使用之前一定要开辟空间(实例化)
        data[0] = 10;
        data[1] = 20;
        data[2] = 30;
        for(int x = 0; x < data.length; x++){
            sout(data[x]);
        }
    }
}

数组作为函数的参数

数组可以作为参数传递给方法

public static void printArray(int[] array){
    for(int i = 0; i < array.length; i++){
        sout(array[i] + " ");
    }
}

printArray(new int[]{3, 1, 2, 6, 4, 2});

数组作为函数的返回值

public static int[] reverse(int[] list){
    int[] result = new int[list.length];
    for(int i = 0, j = result.length - 1; i < list.length; i++, j--){
        result[j] = list[i];
    }
    return result;
}

Arrays类

java.util.Arrays类能方便地操作数组,它提供的所有方法都是静态的

  • 给数组赋值:通过fill方法
  • 对数组排序:通过sort方法,按升序
  • 比较数组:通过equals方法比较数组中元素值是否相等
  • 查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作
public static int binarySearch(Object[], Object key) 
用二分查找算法在给定数组中搜索给定值的对象(Byte,int,double等)
public static boolean equals(long[] a, long[] a2)
如果两个指定的long型数组彼此相等,则返回true。如果两个数组包含相同数量的元素
并且两个元素中的所有相应元素对都是相等的,则认为这两个数组是相等的
public static void fill(int[] a, int val)
将指定的int值分配给指定int型数组指定范围中的每个元素
public static void sort(Object[] a)
对指定对象数组根据其元素的自然顺序进行升序排序