从net到java:java快速入门

Posted Create Sun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从net到java:java快速入门相关的知识,希望对你有一定的参考价值。


学习java那是不可能的,到为什么不学习一下呢。仅为总结。希望自己在不久的将来能书写优美的java程序。加油!奥利给

1.注释

注释的重要性不言而喻,我们不管写什么代码注释必不可少,那么java的注释的书写方式与注释模板是怎么进行的呢?我们来看一下。

package frist;
/*
 * @Description HelloWorld类
 * @Author 王延领
 **/
class HelloWorld {
    /*
    这是我们Java程序的主入口,
    main方法也是程序的主线程。
    */
    public static void main(String[] arg)
    {
        //输出
       System.out.println("wyl");
    }
}

1.1 注释

以上可以看出java的注释主要有三种
单行注释:只能注释当前行,以//开始,直到行结束

 //输出

多行注释:注释一段文字,以/*开始, */结束!

 /*
    这是我们Java程序的主入口,
    main方法也是程序的主线程。
 */

文档注释:用于生产API文档,配合JavaDoc。

/*
 * @Description HelloWorld类
 * @Author 王延领
 **/

1.2 idea注释模版配置

1.2.1 定义java文件头部的注释

File => setting => editor => File and Code Templates-class -Includes
image-20210712143531809

/**
  * @创建人 王延领
  *@创建时间 ${DATE}
  *描述 Todo
**/

以上当你创建一个class的时候就会带上以上信息了

1.2.2 给java类中的方法添加上注释

第一步勾选Enable Live Templates
首先要在上一步中勾选中 Enable Live Templates
image-20210712144107882
第二步新建一个Group
其次要打开LiveTemplates 然后新建一个Group
如图:
img
在弹窗口中输入你想要的group名称,wyl
image-20210712144433114
其中:Abbreviation 为快捷键,当输入w的时候就会提示对应的方法注释模板,j为类的注释模板
image-20210712144649673
Templete Text
注释内容,$$ 为动态模板参数点击Edit Vaariables 选择对应动态值。

image-20210712144955611

/*
 * @描述: TODO
 * @作者 王延领
 * @时间 2021/7/12
 * @版本 1.0
 */
public class wyl {
    /**
     *@描述
     *@参数 [str]
     *@返回值 [java.lang.String]
     *@创建人 王延领
     *@创建时间 2021/7/12
     *@修改人和其它信息
     */
    public String CommentTemplate(String str)
    {
        return str;
    }
}

2.关键字

关键字 说明
private 一种访问控制方式:私用模式
protected 一种访问控制方式:保护模式
public 一种访问控制方式:共用模式
abstract 表明类或者成员方法具有抽象属性
class
extends 表明一个类型是另一个类型的子类型,这里常见的类型有类和接口
final 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变
implements 表明一个类实现了给定的接口
interface 接口
native 用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的
new 用来创建新实例对象
static 表明具有静态属性
strictfp 用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范
synchronized 表明一段代码需要同步执行
transient 声明不用序列化的成员域
volatile 表明两个或者多个变量必须同步地发生变化
break 提前跳出一个块
continue 回到一个块的开始处
return 从成员方法中返回数据
do 用在do-while循环结构中
while 用在循环结构中
if 条件语句的引导词
else 用在条件语句中,表明当条件不成立时的分支
for 一种循环结构的引导词
instanceof 用来测试一个对象是否是指定类型的实例对象
switch 分支语句结构的引导词
case 用在switch语句之中,表示其中的一个分支
default 默认,例如,用在switch语句中,表明一个默认的分支
try 尝试一个可能抛出异常的程序块
catch 用在异常处理中,用来捕捉异常
throw 抛出一个异常
throws 声明在当前定义的成员方法中所有需要抛出的异常
import 表明要访问指定的类或包
package
boolean 基本数据类型之一,布尔类型
byte 基本数据类型之一,字节类型
char 基本数据类型之一,字符类型
double 基本数据类型之一,双精度浮点数类型
float 基本数据类型之一,单精度浮点数类型
int 基本数据类型之一,整数类型
long 基本数据类型之一,长整数类型
short 基本数据类型之一,短整数类型
super 表明当前对象的父类型的引用或者父类型的构造方法
this 指向当前实例对象的引用
void 声明当前成员方法没有返回值
goto 保留关键字,没有具体含义
const 保留关键字,没有具体含义

3.数据类型

image-20210712151302116

3.1.数据类型转换

3.1.1自动类型转换
自动类型转换:容量小的数据类型可以自动转换为容量大的数据类型。
image-20210712152354656
注:如果低级类型为char型,向高级类型(整型)转换时,会转换为对应ASCII码值
3.1.2 强制类型转换
强制类型转换,又被称为造型,用于显式的转换一个数值的类型.
转换方式为:(type)var ,运算符“()”中的type表示将值var想要转换成的目标数据类型。 条件是转换的数据类型必须是兼容的。

double x = 3.14;
int nx = (int)x; //值为3
char c = \'a\';
int d = c+1;
System.out.println(d); //98
System.out.println((char)d); //b

3.1.3.包装类过渡类型转换
eg1:int i=Integer.parseInt(“123”)
说明:此方法只能适用于字符串转化成整型变量
eg2: float f=Float.valueOf(“123”).floatValue()
说明:上例是将一个字符串转化成一个Float对象,然后再调用这个对象的floatValue()方法返回其对应的float数值。
eg3: boolean b=Boolean.valueOf(“123”).booleanValue()
说明:上例是将一个字符串转化成一个Boolean对象,然后再调用这个对象的booleanValue()方法返回其对应的boolean数值。
eg4:double d=Double.valueOf(“123”).doublue()
说明:上例是将一个字符串转化成一个Double对象,然后再调用这个对象的doublue()方法返回其对应的double数值。
eg5: long l=Long.valueOf(“123”).longValue()
说明:上例是将一个字符串转化成一个Long对象,然后再调用这个对象的longValue()方法返回其对应的long数值。
eg6: char=Character.valueOf(“123”).charValue()
说明:上例是将一个字符串转化成一个Character对象

++++++++++++++++++++++++++++++++++++++++++++++++++++++

4.常量、变量、运算符

常量

变量是什么:就是可以变化的量!
我们通过变量来操纵存储空间中的数据,变量就是指代这个存储空间!空间位置是确定的,但是里面放
置什么值不确定!Java是一种强类型语言,每个变量都必须声明其类型。

//数据类型 变量名 = 值;可以使用逗号隔开来声明多个同类型变量。

注意事项:
每个变量都有类型,类型可以是基本类型,也可以是引用类型。
变量名必须是合法的标识符。
变量声明是一条完整的语句,因此每一个声明都必须以分号结束
变量作用域
类变量(静态变量: static variable):独立于方法之外的变量,用 static 修饰。
实例变量(成员变量:member variable):独立于方法之外的变量,不过没有 static 修饰。
局部变量(lacal variable):类的方法中的变量。

变量

常量(Constant):初始化(initialize)后不能再改变值!不会变动的值。

final 常量名=值;
final double PI=3.14;

命名规范

  1. 所有变量、方法、类名:见名知意
  2. 类成员变量:首字母小写和驼峰原则 : monthSalary
  3. 局部变量:首字母小写和驼峰原则
  4. 常量:大写字母和下划线:MAX_VALUE
  5. 类名:首字母大写和驼峰原则: Man, GoodMan
  6. 方法名:首字母小写和驼峰原则: run(), runRun()

运算符

Java 语言支持如下运算符:
算术运算符: +,-,,/,%,++,--
赋值运算符 =
关系运算符: >,<,>=,<=,==,!= instanceof
逻辑运算符: &&,||,!
位运算符: &,|,^,~ , >>,<<,>>> (了解!!!)
条件运算符 ?:
扩展赋值运算符:+=,-=,
=,/=

5.java流转控制

if...else、while、do...while、for、switch...case 在这就不累述了。
跳转:
return
return从一个方法返回,并把控制权交给调用它的语句序;或者直接结束当前的程序;
break
break语句在for、while、do···while循环语句中,经常用于强行退出当前循环;
continue
continue语句用于跳过此次循环,执行下次循环;

6.方法

那么什么是方法呢?
Java方法是语句的集合,它们在一起执行一个功能。
方法是解决一类问题的步骤的有序组合
方法包含于类或对象中
方法在程序中被创建,在其他地方被引用
设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最
好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展。
方法的优点
使程序变得更简短而清晰。
有利于程序维护。
可以提高程序开发的效率。
提高了代码的重用性。

定义

修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}

修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需
的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参
数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
形式参数:在方法被调用时用于接收外界输入的数据。
实参:调用方法时实际传给方法的数据。
方法体:方法体包含具体的语句,定义该方法的功能。

方法的重载

就是说一个类的两个方法拥有相同的名字,但是有不同的参数列表。

可变参数

在方法声明中,在指定参数类型后加一个省略号(...) 。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声
明。

typeName... parameterName

递归

自己调用自己

7.数组

数组的定义:

数组是相同类型数据的有序集合.
数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们.

数组的四个基本特点:

  1. 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
  2. 其元素必须是相同类型,不允许出现混合类型。
  3. 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
  4. 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量

数组声明

dataType[] arrayRefVar; // 首选的方法
或
dataType arrayRefVar[]; // 效果相同,但不是首选方法

创建数组

arrayRefVar = new dataType[1 arraySize];

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

三种初始化

静态初始化
除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。

int[] a = {1,2,3};
Man[] mans = {new Man(1,1),new Man(2,2)};

动态初始化
数组定义、为数组元素分配空间、赋值的操作、分开进行。

int[] a = new int[2];
a[0]=1;
a[1]=2;

数组的默认初始化
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实
例变量同样的方式被隐式初始化。

public static void main(String[] args) {
int[] a=new int[2];
boolean[] b = new boolean[2];
String[] s = new String[2];
System.out.println(a[0]+":"+a[1]); //0,0
System.out.println(b[0]+":"+b[1]); //false,false
System.out.println(s[0]+":"+s[1]); //null, null
}

数组边界

下标的合法区间:[0, length-1],如果越界就会报错;

for 和For-Each 循环

for(type element: array){
System.out.println(element);
}
for (int i = 1; i < myList.length; i++) {
System.out.println(myList[i]);
}

多维数组

type[][] typeName = new type[typeLength1][1 typeLength2];

Arrays 类

数组的工具类java.util.Arrays
java.util.Arrays 类能方便地操作数组. 使用之前需要导包!
具有以下常用功能:
给数组赋值:通过 fill 方法。
对数组排序:通过 sort 方法,按升序。
比较数组:通过 equals 方法比较数组中元素值是否相等。
查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。
转换为list: 通过asList(a)进行转换

8.面向对象

万物皆为对象!!!对象是抽象概念的具体实例。

以类的方式组织代码,以对象的组织(封装)数据就是面向对象

继承

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。

class 父类 {
}
class 子类 extends 父类 {
}

public interface A {
    public void eat();
    public void sleep();
}
 
public interface B {
    public void show();
}
 
public class C implements A,B {
}

为什么要继承,因为有重复。所以才继承,进而我们就知道了。父类就是公共部分的定义或规则

Java 不支持多继承(只能继承一个类),但支持多重继承。

image-20210809181238809

特点

  • 子类拥有父类非 private 的属性、方法。

  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

  • 子类可以用自己的方式实现父类的方法。

  • Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。

  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)

super 与 this 关键字

class Animal {
  void eat() {
    System.out.println("animal : eat");
  }
}
 
class Dog extends Animal {
  void eat() {
    System.out.println("dog : eat");
  }
  void eatTest() {
    this.eat();   // this 调用自己的方法
    super.eat();  // super 调用父类方法
  }
}
 
public class Test {
  public static void main(String[] args) {
    Animal a = new Animal();
    a.eat();
    Dog d = new Dog();
    d.eatTest();
  }
}
animal : eat
dog : eat
animal : eat

final关键字
final 关键字声明类可以把类定义为不能继承的,即最终类;

class SuperClass {
  private int n;
  SuperClass(){
    System.out.println("SuperClass()");
  }
  SuperClass(int n) {
    System.out.println("SuperClass(int n)");
    this.n = n;
  }
}
// SubClass 类继承
class SubClass extends SuperClass{
  private int n;
  
  SubClass(){ // 自动调用父类的无参数构造器
    System.out.println("SubClass");
  }  
  
  public SubClass(int n){ 
    super(300);  // 调用父类中带有参数的构造器
    System.out.println("SubClass(int n):"+n);
    this.n = n;
  }
}
// SubClass2 类继承
class SubClass2 extends SuperClass{
  private int n;
  
  SubClass2(){
    super(300);  // 调用父类中带有参数的构造器
    System.out.println("SubClass2");
  }  
  
  public SubClass2(int n){ // 自动调用父类的无参数构造器
    System.out.println("SubClass2(int n):"+n);
    this.n = n;
  }
}
public class TestSuperSub{
  public static void main (String args[]){
    System.out.println("------SubClass 类继承------");
    SubClass sc1 = new SubClass();
    SubClass sc2 = new SubClass(100); 
    System.out.println("------SubClass2 类继承------");
    SubClass2 sc3 = new SubClass2();
    SubClass2 sc4 = new SubClass2(200); 
  }
}
------SubClass 类继承------
SuperClass()
SubClass
SuperClass(int n)
SubClass(int n):100
------SubClass2 类继承------
SuperClass(int n)
SubClass2
SuperClass()
SubClass2(int n):200

构造函数

子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。

如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

重写(Override)与重载(Overload)

重写(Override)

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写

class Animal{
   public void move(){
      System.out.println("动物可以移动");
   }
}
 
class Dog extends Animal{
   public void move(){
      System.out.println("狗可以跑和走");
   }
}
 
public class TestDog{
   public static void main(String args[]){
      Animal a = new Animal(); // Animal 对象
      Animal b = new Dog(); // Dog 对象
      a.move();// 执行 Animal 类的方法
      b.move();//执行 Dog 类的方法
   }
}
动物可以移动
狗可以跑和走

方法的重写规则

  • 参数列表与被重写方法的参数列表必须完全相同。

  • 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。

  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。

  • 父类的成员方法只能被它的子类重写。

  • 声明为 final 的方法不能被重写。

  • 声明为 static 的方法不能被重写,但是能够被再次声明。

  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。

  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。

  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。

  • 构造方法不能被重写。

  • 如果不能继承一个类,则不能重写该类的方法。

重载(Overload)

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

最常用的地方就是构造器的重载。

public class Overloading {
    public int test(){
        System.out.println("test1");
        return 1;
    }
 
    public void test(int a){
        System.out.println("test2");
    }   
 
    //以下两个参数类型顺序不同
    public String test(int a,String s){
        System.out.println("test3");
        return "returntest3";
    }   
 
    public String test(String s,int a){
        System.out.println("test4");
        return "returntest4";
    }   
 
    public static void main(String[] args){
        Overloading o = new Overloading();
        System.out.println(o.test());
        o.test(1);
        System.out.println(o.test(1,"test3"));
        System.out.println(o.test("test4",1));
    }
}

重载规则:

  • 被重载的方法必须改变参数列表(参数个数或类型不一样);

  • 被重载的方法可以改变返回类型;

  • 被重载的方法可以改变访问修饰符;

  • 被重载的方法可以声明新的或更广的检查异常;

  • 方法能够在同一个类中或者在一个子类中被重载。

  • 无法以返回值类型作为重载函数的区分标准。

    区别点 重载方法 重写方法
    参数列表 必须修改 一定不能修改
    返回类型 可以修改 一定不能修改
    异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常
    访问 可以修改 一定不能做更严格的限制(可以降低限制)

多态

多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作。

多态性是对象多种表现形式的体现。

多态的优点

  1. 消除类型之间的耦合关系
  2. 可替换性
  3. 可扩充性
  4. 接口性
  5. 灵活性
  6. 简化性

多态存在的三个必要条件

继承
重写
父类引用指向子类对象:Parent p = new Child();

class Shape {
    void draw() {}
}
 
class Circle extends Shape {
    void draw() {
        System.out.println("Circle.draw()");
    }
}
 
class Square extends Shape {
    void draw() {
        System.out.println("Square.draw()");
    }
}
 
class Triangle extends Shape {
    void draw() {
        System.out.println("Triangle.draw()");
    }
}

虚函数

虚函数的存在是为了多态。

Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是Java的默认行为。如果 Java 中不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数。

多态的实现方式

方式一:重写:

方式二:接口

方式三:抽象类和抽象方法

抽象类

拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明.

abstract class A{//定义一个抽象类
	public void fun(){//普通方法
		System.out.println("存在方法体的方法");
	}
	public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
	
}

继承抽象类

我们可以通过以下方式继承 Employee 类的属性

抽象类的使用原则
(1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
(2)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;
(3)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;
(4)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。);

package com.wz.abstractdemo;

abstract class A{//定义一个抽象类
	
	public void fun(){//普通方法
		System.out.println("存在方法体的方法");
	}
	
	public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
	
}
//单继承
class B extends A{//B类是抽象类的子类,是一个普通类

	@Override
	public void print() {//强制要求覆写
		System.out.println("Hello World !");
	}
	
}
public class TestDemo {

	public static void main(String[] args) {
		A a = new B();//向上转型
		
		a.print();//被子类所覆写的过的方法
	}
}
Hello World !

封装

封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

要访问该类的代码和数据,必须通过严格的接口控制。

封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。

适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

封装的优点

  1. 良好的封装能够减少耦合。
  2. 类内部的结构可以自由修改。
  3. 可以对成员变量进行更精确的控制。
  4. 隐藏信息,实现细节。

接口

在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口与类相似点

  1. 一个接口可以有多个方法。
  2. 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
  3. 接口的字节码文件保存在 .class 结尾的文件中。
  4. 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别

  1. 接口不能用于实例化对象。
  2. 接口没有构造方法。
  3. 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
  4. 接口不能包含成员变量,除了 static 和 final 变量。
  5. 接口不是被类继承了,而是要被类实现。
  6. 接口支持多继承。

接口特性

  1. 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
  2. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
  3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

抽象类和接口的区别

  1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。

  2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。

  3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法

  4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

[可见度] interface 接口名称 [extends 其他的接口名] {
        // 声明变量
        // 抽象方法
}
/* 文件名 : NameOfInterface.java */
import java.lang.*;
//引入包
 
public interface NameOfInterface
{
   //任何类型 final, static 字段
   //抽象方法
}

接口有以下特性

  • 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
  • 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
  • 接口中的方法都是公有的。

枚举

枚举是一个特殊的类,一般表示一组常量.每个枚举都是通过 Class 在内部实现的,且所有的枚举值都是 public static final 的。

enum Color
{
    RED, GREEN, BLUE;
}
 
public class Test
{
    // 执行输出结果
    public static void main(String[] args)
    {
        Color c1 = Color.RED;
        System.out.println(c1);
    }
}
RED

values(), ordinal() 和 valueOf() 方法

enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Seriablizable 和 java.lang.Comparable 两个接口。

values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:

  • values() 返回枚举类中所有的值。

  • ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。

  • valueOf()方法返回指定字符串值的枚举常量。

    enum Color
    {
        RED, GREEN, BLUE;
    }
     
    public class Test
    {
        public static void main(String[] args)
        {
            // 调用 values()
            Color[] arr = Color.values();
            // 迭代枚举
            for (Color col : arr)
            {
                // 查看索引
                System.out.println(col + " at index " + col.ordinal());
            }
            // 使用 valueOf() 返回枚举常量,不存在的会报错 IllegalArgumentException
            System.out.println(Color.valueOf("RED"));
            // System.out.println(Color.valueOf("WHITE"));
        }
    }
    
    RED at index 0
    GREEN at index 1
    BLUE at index 2
    RED
    

    枚举成员

    枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用。

    enum Color
    {
        RED, GREEN, BLUE;
     
        // 构造函数
        private Color()
        {
            System.out.println("Constructor called for : " + this.toString());
        }
        public void colorInfo()
        {
            System.out.println("Universal Color");
        }
    }
    

包(package)

为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

包的 3 个作用如下

  1. 区分相同名称的类。

  2. 能够较好地管理大量的类。

  3. 控制访问范围。

定义

 ```java

package 包名;
```
Java 包的命名规则如下:

  • 包名全部由小写字母(多个单词也全部小写)。
  • 如果包名包含多个层次,每个层次用“.”分割。
  • 包名一般由倒置的域名开头,比如 com.baidu,不要有 www。
  • 自定义包不能 java 开头

包导入

\\\\如果使用不同包中的其它类,需要使用该类的全名(包名+类名)
    example.Test test = new example.Test();
\\\\import 包名+类名;
import example.Test;\\\\or
import example.*;

系统包

说明
java.lang Java 的核心类库,包含运行 Java 程序必不可少的系统类,如基本数据类型、基本数学函数、 字符串处理、异常处理和线程类等,系统默认加载这个包
java.io Java 语言的标准输入/输出类库,如基本输入/输出流、文件输入/输出、过滤输入/输出流等
java.util 包含如处理时间的 Date 类,处理动态数组的 Vector 类,以及 Stack 和 HashTable 类
java.awt 构建图形用户界面(GUI)的类库,低级绘图操作 Graphics 类、图形界面组件和布局管理 (如 Checkbox 类、Container 类、LayoutManger 接口等),以及用户界面交互控制和事 件响应(如 Event 类)
java.awt.image 处理和操纵来自网上的图片的 Java 工具类库
java.wat.peer 很少在程序中直接用到,使得同一个 Java 程序在不同的软硬件平台上运行
java.net 实现网络功能的类库有 Socket 类、ServerSocket 类
java.lang.reflect 提供用于反射对象的工具
java.util.zip 实现文件压缩功能
java.awt.datatransfer 处理数据传输的工具类,包括剪贴板、字符串发送器等
java.sql 实现 JDBC 的类库
java.rmi 提供远程连接与载入的支持
java. security 提供安全性方面的有关支持

9.异常处理

异常处理的概念

是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件)。

关键字

Java异常机制用到的几个关键字:try、catch、finally、throw、throws。

try -- 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常
时,异常就被抛出。
catch -- 用于捕获异常。catch用来捕获try语句块中发生的异常。
finally -- finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络
连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语
句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
throw -- 用于抛出异常。
throws -- 用在方法签名中,用于声明该方法可能抛出的异常。

 try{
        可能会发生的异常
    }catch(异常类型 异常名(变量)){
        针对异常进行处理的代码
    }catch(异常类型 异常名(变量)){
        针对异常进行处理的代码
    }...
    [finally{
        释放资源代码;
    }]

Error与Exception区别

Error(错误)是系统中的错误,程序员是不能改变的和处理的,是在程序编译时出现的错误,只能通过修改程序才能修正。一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。
Exception(异常)表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

throw与throws区别

throw:指的是在方法中人为抛出一个异常对象(这个异常对象可能是自己实例化或者抛出已存在的);
throw ThrowableInstance;
throws:在方法的声明上使用,表示此方法在调用时必须处理异常。
throw new NullPointerException("demo");
image-20210728140018762

​ Java异常层次结构图(网上获取)

10.集合框架

所有集合类都位于 java.util 包下。Java的集合类主要由两个接口派生而出:Collection 和 Map,Collection 和 Map 是 Java 集合框架的根接口,这两个接口又包含了一些子接口或实现类。

集合框架被设计成要满足以下几个目标:

  • 该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。
  • 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。
  • 对一个集合的扩展和适应必须是简单的。

集合框架都包含如下内容:

  • 接口:是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象

  • 实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。

  • 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。

    image-20210728172402028

Collection是一个基本的集合接口,Collection中可以容纳一组集合元素(Element)

Collection 接口

Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。

List

List接口是一个有序, 元素可重复的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。

  1. ArrayList

底层数据结构是数组,查改快,增删慢。

非线程安全,效率高

方法:

image-20210728173620540

排序

import java.util.Collections;  // 引入 Collections 类
Collections.sort(sites); *// 字母排序*
  1. Vector

底层数据结构是数组,查改快,增删慢。

线程安全,效率低

  1. LinkedList

底层数据结构是链表,查改慢,增删快。

非线程安全,效率高

以下情况使用 LinkedList :

  • 你需要通过循环迭代来访问列表中的某些元素。
  • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

LinkedList 继承了 AbstractSequentialList 类。

LinkedList 实现了 Queue 接口,可作为队列使用。

LinkedList 实现了 List 接口,可进行列表的相关操作。

LinkedList 实现了 Deque 接口,可作为队列使用。

LinkedList 实现了 Cloneable 接口,可实现克隆。

LinkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

方法:

image-20210728174512617

Set

Set 接口存储一组唯一,无序的对象。

  1. HashSet

底层数据结构是哈希表。(无序,唯一)

依赖两个方法:hashCode()和equals() 保证元素唯一性

// 引入 HashSet 类      
import java.util.HashSet;

public class RunoobTest {
    public static void main(String[] args) {
    HashSet<String> sites = new HashSet<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");  // 重复的元素不会被添加
        System.out.println(sites);
    }
}

以上代码只会输出一个Runoob。

  1. LinkedHashSet

底层数据结构是链表和哈希表。(FIFO插入有序,唯一)

1.由链表保证元素有序

2.由哈希表保证元素唯一

  1. TreeSet

底层数据结构是红黑树。(唯一,有序)

如何保证元素排序的呢? 自然排序,比较器排序

Set和List的区别

  • Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
  • Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>
  • List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector>

image-20210728172343233

Map与Collection是并列关系。Map提供键(key)到值(value)的映射。一个Map中不能包含相同的键,每个键只能映射一个值。

  1. HashMap

无序,非线程安全,效率高。HashMap允许null值(key和value都允许)。

image-20210728174945196

  1. HashTable

无序,线程安全,效率低。除构造函数外,HashTable的所有 public 方法声明中都有 synchronized关键字,而HashMap的源码中则没有。HashTable不允许null值(key和value都允许)。

  1. TreeMap

有序,非线程安全,效率高(O(logN)),但比不上HashMap (O(1))。

11.流(Stream)、文件(File)和IO

Java.io 包中定义了多个流类型(类或抽象类)来实现输入/输出功能;

img

可以从不同的角度对其进行分
类:
1.按数据流的方向不同可以分为输入流【InputStream(字节流),Reader(字符流)】和输出流【OutPutStream(字节流),Writer(字符流)】
2.按照处理数据单位不同可以分为字节流【一个字节(Byte)是8位(bit))】和字符流【一个字符是2个字节】
3.按照功能不同可以分为节点流和处理流

img

4.按照操作对象分

img

InputStream 和 OutputStream

img

img

import java.io.*;
 
public class fileStreamTest {
    public static void main(String[] args) {
        try {
            byte bWrite[] = { 11, 21, 3, 40, 5 };
            OutputStream os = new FileOutputStream("test.txt");
            for (int x = 0; x < bWrite.length; x++) {
                os.write(bWrite[x]); // writes the bytes
            }
            os.close();
 
            InputStream is = new FileInputStream("test.txt");
            int size = is.available();
 
            for (int i = 0; i < size; i++) {
                System.out.print((char) is.read() + "  ");
            }
            is.close();
        } catch (IOException e) {
            System.out.print("Exception");
        }
    }
}

上面的程序首先创建文件test.txt,并把给定的数字以二进制形式写进该文件,同时输出到控制台上。

以上代码由于是二进制写入,可能存在乱码,你可以使用以下代码实例来解决乱码问题:

//文件名 :fileStreamTest2.java
import java.io.*;
 
public class fileStreamTest2 {
    public static void main(String[] args) throws IOException {
        File f = new File("a.txt");
        FileOutputStream fop = new FileOutputStream(f);
        // 构建FileOutputStream对象,文件不存在会自动新建
        OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
        // 构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk
        writer.append("中文输入");
        // 写入到缓冲区
        writer.append("\\r\\n");
        // 换行
        writer.append("English");
        // 刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入
        writer.close();
        // 关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉
        fop.close();
        // 关闭输出流,释放系统资源
        FileInputStream fip = new FileInputStream(f);
        // 构建FileInputStream对象
        InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
        // 构建InputStreamReader对象,编码与写入相同
        StringBuffer sb = new StringBuffer();
        while (reader.ready()) {
            sb.append((char) reader.read());
            // 转成char加到StringBuffer对象中
        }
        System.out.println(sb.toString());
        reader.close();
        // 关闭读取流
        fip.close();
        // 关闭输入流,释放系统资源
 
    }
}

Reader 流与Writer流

img

img

Reader ,Write与InputStream ,OutputStream: 唯一的区别就在于读的数据单位不同分别为(16bit),(8bit)

创建读取目录:

import java.io.File;
 
public class CreateDir {
    public static void main(String[] args) {
        String dirname = "/tmp/user/java/bin";
        File d = new File(dirname);
        // 现在创建目录
        d.mkdirs();
    }
}
import java.io.File;
 
public class DirList {
    public static void main(String args[]) {
        String dirname = "/tmp";
        File f1 = new File(dirname);
        if (f1.isDirectory()) {
            System.out.println("目录 " + dirname);
            String s[] = f1.list();
            for (int i = 0; i < s.length; i++) {
                File f = new File(dirname + "/" + s[i]);
                if (f.isDirectory()) {
                    System.out.println(s[i] + " 是一个目录");
                } else {
                    System.out.println(s[i] + " 是一个文件");
                }
            }
        } else {
            System.out.println(dirname + " 不是一个目录");
        }
    }
}

删除

import java.io.File;
 
public class DeleteFileDemo {
    public static void main(String[] args) {
        // 这里修改为自己的测试目录
        File folder = new File("/tmp/java/");
        deleteFolder(folder);
    }
 
    // 删除文件及目录
    public static void deleteFolder(File folder) {
        File[] files = folder.listFiles();
        if (files != null) {
            for (File f : files) {
                if (f.isDirectory()) {
                    deleteFolder(f);
                } else {
                    f.delete();
                }
            }
        }
        folder.delete();
    }
}

缓存流

是处理流的一种,它是要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,避免频繁读写硬盘, 提高了读写的效率。同时增加了一些新的方法。

BufferedReader(Reader in)
BufferedReader(Reader in,int sz) //sz 为自定义缓冲区的大小
BufferedWriter(Writer out)
BufferedWriter(Writer out,int sz)
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in,int size)
BufferedOutputStream(InputStream in)
BufferedOutputStream(InputStream in,int size)

BufferedInputStream

package com.kuang.chapter;
import java.io.*;
public class TestBufferStream {
public static void main(String args[]) {
FileInputStream fis = null;
File f = new File("a.txt");
try {
fis = new FileInputStream( f);
// 在FileInputStream节点流的外面套接一层处理流BufferedInputStream
BufferedInputStream bis = new BufferedInputStream(fis);
int c = 0;
System.out.println((char) bis.read());
System.out.println((char) bis.read());
bis.mark(100);// 在第100个字符处做一个标记
for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) {
System.out.print((char) c);
}
System.out.println();
bis.reset();// 重新回到原来标记的地方
for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) {
System.out.print((char) c);
}
bis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}

BufferedReader

package com.kuang.chapter;
import java.io.*;
public class TestBufferStream{
public static void main(String args[]){
try{
BufferedWriter bw = new BufferedWriter(new FileWriter("a\\\\Student.txt"));
//在节点流FileWriter的外面再套一层处理流BufferedWriter
String s = null;
for(int i=0;i<100;i++){
s = String.valueOf(Math.random());//“Math.random()”将会生成一系列介于0~1之间的随机数。
// static String valueOf(double d)这个valueOf()方法的作用就是把
一个double类型的数转换成字符串
//valueOf()是一个静态方法,所以可以使用“类型.静态方法名”的形式来调用
bw.write(s);//把随机数字符串写入到指定文件中
bw.newLine();//调用newLine()方法使得每写入一个随机数就换行显示
}
bw.flush();//调用flush()方法清空缓冲区
BufferedReader br = new BufferedReader(new FileReader("a:\\\\Student.txt"));
//在节点流FileReader的外面再套一层处理流BufferedReader
while((s = br.readLine())!=null){
//使用BufferedReader处理流里面提供String readLine()方法读取文件中的数据时是一行一行读取的
//循环结束的条件就是使用readLine()方法读取数据返回的字符串为空值后则表
示已经读取到文件的末尾了。
System.out.println(s);
}
bw.close();
br.close();
}catch(Exception e){
e.printStackTrace();
}
}
}

转换流

InputStreamReader 和 OutputStreamWriter 用于字节数据到字符数据之间的转换
InputStreamReader 需要和 InputStream “套接” 。
OutputStreamWriter 需要和 OutputStream “套接” 。
转换流在构造时可以指定其编码集合

import java.io.*;
public class TestTransform1 {
public static void main(String args[]) {
try {
    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:/char.txt"));
    osw.write("熊方园真烦人");// 把字符串写入到指定的文件中去
    System.out.println(osw.getEncoding());// 使用getEncoding()方法取得当前系统的默认字符编码
    osw.close();
    osw = new OutputStreamWriter(new FileOutputStream("D:\\\\java\\\\char.txt", true), "utf-8");// 如果在调用FileOutputStream的构造方法时没有加入true,那么新加入的字符    串就会替换掉原来写入的字符串,在调用构造方法时指定了字符的编码
    osw.write("不想搭理她");// 再次向指定的文件写入字符串,新写入的字符串加入到原来字符串的后面
    System.out.println(osw.getEncoding());
    osw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

数据流

数据流 DataInputStream DataOutputStream 【分别继承自InputStream 和 OutputStream】等-提供将基础数据类型写入到文件中,或者读取出来.提供了可以存取与机器无关的Java原始类型数据(int,double等)的方法。

public static void main(String args[]){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//在调用构造方法时,首先会在内存里面创建一个ByteArray字节数组
DataOutputStream dos = new DataOutputStream(baos);
//在输出流的外面套上一层数据流,用来处理int,double类型的数
try{
    dos.writeDouble(Math.random());//把产生的随机数直接写入到字节数组
    ByteArray中
    dos.writeBoolean(true);//布尔类型的数据在内存中就只占一个字节
    ByteArrayInputStream bais = new
    ByteArrayInputStream(baos.toByteArray());
        System.out.println(bais.available());
    DataInputStream dis = new DataInputStream(bais);
    System.out.println(dis.readDouble());//先写进去的就先读出来,调用readDouble()方法读取出写入的随机数
    System.out.println(dis.readBoolean());//后写进去的就后读出来,这里面的读取顺序不能更改位置,否则会打印出不正确的结果
    dos.close();
    bais.close();
}catch(Exception e){
e.printStackTrace();
}
}

打印流

打印流是输出信息最方便的类,注意包含字节打印流PrintStream和字符打印流:PrintWriter。打印流提供了非常方便的打印功能,
可以打印任何类型的数据信息,例如:小数,整数,字符串。


对象流

对象的输入输出流的作用: 用于写入对象 的信息和读取对象的信息。 使得对象持久化。
ObjectInputStream : 对象输入流
ObjectOutPutStream :对象输出流

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

//创建要写入磁盘的类,这个类需要实现接口 Serializable(可系列化的)
class Student implements Serializable{
    // 在这里保证了serialVersionUID 的唯一性,防止属性变量的临时改变,从而造成写入id与读取id不同
    private static final long serialVersionUID = 1L;
    int id ; //额外需要添加一个属性
    String name ;
    transient String sex; //transient修饰属性,表示暂时的,则这个属性不会被写入磁盘
    transient int age;
    public Student(String name,String sex,int age){
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
}

public class objectIO {

    /**
     * @param args
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // TODO Auto-generated method stub

        createObj();
        readObj();
    }
    //(一)先写入对象
    public static void createObj() throws IOException {
        //1.创建目标路径
        File file = new File("C:\\\\Users\\\\bg\\\\Desktop\\\\objTest.txt");
        //2.创建流通道
        FileOutputStream fos = new FileOutputStream(file);
        //3.创建对象输出流
        ObjectOutputStream objOP = new ObjectOutputStream(fos);
        //4.创建类对象,并初始化
        Student stu = new Student("玛丽苏", "男", 18);
        //5.向目标路径文件写入对象
        objOP.writeObject(stu);
        //6.关闭资源
        objOP.close();
    }
    //再读取对象
    public static void readObj() throws IOException, ClassNotFoundException {
        File file = new File("C:\\\\Users\\\\bg\\\\Desktop\\\\objTest.txt");
        FileInputStream fis = new FileInputStream(file);
        ObjectInputStream objIP = new ObjectInputStream(fis);
        //读取对象数据,需要将对象流强制转换为 要写入对象的类型
        Student stu = (Student)objIP.readObject();
        System.out.println("\\n name:"+stu.name+"\\n sex:"+stu.sex+"\\n age:"+stu.age);
        objIP.close();
    }
}

流的关闭顺序

  1. 一般情况下是:先打开的后关闭,后打开的先关闭
  2. 另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b。例如,处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
  3. 可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法。

12.多线程

进程与线程

线程的创建

继承Thread类,实现Runnable接口,实现Callable接口

1.继承Thread类

public class ThreadCreateDemo1 {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start(); //调用start()方法启动线程,线程不一定立即执行,CPU安排调度
    }
}
class MyThread extends Thread {//继承Thread类
    @Override
    public void run() {//重写run()方法,编写线程执行体
        super.run();
        System.out.println("hellow_world!");
    }
}

2.实现Runnable接口

public class ThreadCreateDemo2 {
    //创建线程对象,调用start()方法启动线程
    public static void main(String[

以上是关于从net到java:java快速入门的主要内容,如果未能解决你的问题,请参考以下文章

Apache Flink从入门到放弃——快速上手(Java版)

Apache Flink从入门到放弃——快速上手(Java版)

Apache Flink从入门到放弃——快速上手(Java版)

JAVA WEB快速入门之环境搭建

快速从入门到精通!成都java培训机构比较

快速从入门到精通!熬夜整理Java高频面试题