Java 基础

本文最后更新于 2025年4月13日 凌晨

一些学习 Java 的笔记,篇幅有点长嘻嘻 ^__^ ~

数据类型

八大数据类型

数值型

​ 1.整数类型(byte,short,int,long)

​ 2.浮点类型(float,double)

1
2
long num =30L;			// long 型加 L
float num1 = 50.1F; // float 型加 F
字符型(char)2个字节
布尔型(boolean)

引用数据类型

类(class)

接口(interface)

数组([])

运算符

算术运算符

+-作为单元运算符存在时,表示正负

1.+

+左右两边没有字符串,则进行数值运算。

+左右两边有字符串,进行字符串拼接,如果不是字符串会转换成字符串

1
2
3
4
System.out.println(100+98);						//198
System.out.println('a'+1); //98
System.out.println("a"+1+3); //a13
System.out.println(1+3+"a"); //4a

2.%

a%b==a-a/b*b

1
2
3
4
System.out.println(10%4);						//2
System.out.println(-10%4); //-2
System.out.println(10%-4); //2
System.out.println(-10%-4); //-2

逻辑运算符

& 和|不管真假都运算

HEX编码

数组

一维数组

动态初始化

​ 元素类型[ ] 数组名= new 元素类型[数组长度];

1
int[]  arr=new  int[5];

静态初始化

元素类型[ ] 数组名=new 元素类型[ ]{元素,元素,元素…};

1
2
int[]  arr=new int[ ]{1,2,3,4,5};
int[] arr={1,2,3,4,5};

相当于

1
2
int[] arr=new int[5];
arr[0]=1,arr[1]=2,arr[2]=3,arr[3]=4,arr[4]=5;

e.g

1
2
char[] chars={'a','b','c'};
char chars1[]=new char[]{'a','b','c'};

数组创建后没有赋值就是默认值

1
2
3
4
5
6
7
long/int/short/byte 0

float/double 0.0

boolean false

String null

数组使用步骤

声明数组->开辟空间->给数组各个元素赋值->使用数组

数组成员的赋值和读取

下标越界会抛异常

数组下标越界异常

1
2
int[] arr=new int[3];
System.out.println(arr[3]); //有效下标为012

空指针异常

1
int[] arr;

数组遍历

数组名.length获取数组长度

数组扩容

值传递与引用传递

a.栈内存

​ 存储局部变量,离开作用域,自动释放

b.堆内存

​ 数组和对象,通过 new 建立的实例都放在堆内存中

​ 当没有任何引用指向实例的时候,gc 会不定时回收

​ 实例中的变量都有默认初始化值,建议手动初始化

​ 引用类型的初始化为 null

c.方法区、本地方法区

二维数组

二维数组定义和长度

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
{
{123},
{456}
}
int[][] arr=new int[2][3];
arr[0][0]=100;
System.out.println(arr.length); //2,二维数组长度
System.out.println(arr[0].length);
System.out.println(arr[1].length); //3,个数



{
{0,0},
{0,0,0}
}
int[][] arr2=new int[2][]; //先开辟空间,2行,再继续取列数
arr2[0]=new int[2];
arr2[1]=new int[3];



int[][] arr3={
{1,2,3},
{4,5,6}
}

二维数组其他定义方式

1
2
int[] x;		int x[];
int[][] y; int y[][]; int [] y[];

e.g.

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
1.
String foo="blue";
boolean[] bar=new boolean[2];
if(bar[0]){
foo="green";
}
System.out.println(foo);
//输出blue
2.
char[] arr1 = {'a', 'b', 'c', 'd'};
char[] arr2 = arr1;
arr2[2] = 'x';
System.out.println(arr1[2]);
//输出x
3.
随机生成十个整数
int[] arr=new int[10];
for(int i=0;i<10;i++){
arr[i]=(int)(Math.random()*100);
}

for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
//倒序打印
for(int i=arr.length-1;i>=0;i--){
System.out.println(arr[i]);
}
//求均值
int sum=arr[0];
for(int i=1;i<arr.length;i++){
sum +=arr[i];
}
System.out.println("均值"+sum/arr.length);
//求最大值及其索引
int max=arr[0];
int maxIndex=0;
for(int i=0;i<arr.length;i++){
if(max<arr[i]){
max=arr[i];
maxIndex=i;
}
}
System.out.println(max+" "+maxIndex);

进制转换

1
2
3
4
5
6
7
8
9
10
11
int a=164;
StringBuilder stringBuilder=new StringBuilder();
char[] chars={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
while(a>0){
int index=a%16;
char temp=chars[index];
stringBuilder.append(temp);
a=a/16;
}
System.out.println(stringBuilder.reverse().toString());

类、属性、对象

类的定义方法

方法(函数/成员方法/ method )的定义

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
访问修饰符 返回值类型 方法名(形参列表){
语句;
...
return 返回值;
}
e.g.
void butt3rf1y(){...}
//可以类比C语言的函数定义

类内部调用
public class Main {
public static void main(String[] args) {
test();
}
static void test() {
System.out.println("test");
}
}

类外部调用
Main.java
public class Main {
public static void main(String[] args) {
Cat cat=new Cat();
cat.miao();
}
}
Cat.java
public class Cat {
void miao(){
System.out.println("喵");
return;(可以省略)
}
}

返回值

一个方法只能返回一个值,要返回多个值可以用数组,可以为任意类型,包括基本数据类型和引用类型,返回值类型必须和 return 的值类型一致或兼容

当函数没有返回值时,return 可以省略

参数(类比C语言)

一个方法可以没有参数或多个参数,中间用逗号隔开(类比C语言)

方法体

类比C语言函数体

不可以在方法体内部定义方法

方法传参机制

a.方法嵌套顺序

执行方法时会独立开辟栈空间,执行完毕或执行到 return 时,就会返回到调用方法的地方,返回后继续执行后面的代码,main 方法执行完毕,程序结束

b.值传递/值拷贝,形参任何改变不影响实参

c.引用传递,传递地址,形参改变可能影响实参

d.String 的传递

属性

属性(成员变量/字段/ field )的概念

属性定义语法与变量一致,多了访问修饰符

1
访问修饰符 属性类型 属性名

属性类型可以为任意类型,可以是基本数据类型和引用类型,如果没有初始化,有默认值,和数组一致

Static

静态属性(类属性)与实例属性(对象属性)

静态属性,只有一份,可以通过 类名.属性名/对象.属性名来赋值和访问

实例属性,每个对象有一份,只能通过 对象.属性名来赋值和访问

静态方法和实例方法(对象方法)

静态方法只能调用静态方法,不能访问实例属性

实例方法中可以调用静态方法和实例方法,也可以访问静态属性和实例属性

补全method方法

1
2
3
4
5
System.out.println(method(method(100.2,1.0),100))

static double method(double a,double b){
return a+b;
}

e.g.

定义一个find方法,实现对字符串数组元素进行查找,并返回索引,找不到返回-1;

1
2
3
4
5
6
7
8
9
10
11
12
13
String[] a=new String[]{"a","b","c"};
String b="c";
System.out.println(find(a,b));

}
static int find(String[] a,String b) {
for (int i = 0; i < a.length; i++) {
if (a[i] == b) {
return i;
}
}
return -1;
}

重载

同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型,参数顺序不同即可,与返回值类型无关,只看参数列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Hello {
public static void main(String[] args) throws Exception{

System.out.println("abc0");
System.out.println('a');
System.out.println(false);
System.out.println(1000.1);
System.out.println(123);
test("x");
}
static void test(String a){
System.out.println(a);
}
static void test(int a){
System.out.println(a);
}
}

可变参数

1
int sum(int... nums){ }

可变参数本质就是数组,实参可以为0个或任意多个

可变参数的实参可以为数组,这时候只能传一个参数

形参列表中只能出现一个可变参数

可变参数可以和普通参数以前放在形参列表,但必须保证可变参数在最后一个西餐列表中只能出现一个可变参数

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) throws Exception{

int[] a=new int[]{1,2,3,4,5,6,7,8,9,10};
System.out.println(sum("java","cpp",a));
}
static int sum(String d,String b,int... a){
int result=0;
for(int i=0;i<a.length;i++){
result+=a[i];
}
return result;
}

构造器/构造方法/构造函数

构造器特点

与类名一致,无返回值

当对象创建时,会自动调用对应的构造器

如果没有定义构造器,会自动生成默认的无参构造器(默认构造器)

一个类可以定义多个不同的构造器,即构造器重载

一旦定义了构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,除非自己显示的定义一下

对象创建流程

1
2
3
4
5
6
7
8
9
class Person{
int age=90;
String name;
Person(String n,int a){
name=n;
age=a;
}
}
Person p=new Person("abc",31);

加载 Person 类信息,只会加载一次

在堆中分配空间(地址)

完成对象初始化

1
2
3
默认初始化   age=0   name=null
显示初始化 age=90 name=null
构造器初始化 age=31 name=abc

在对象在堆中的地址,返回给 p (p是对象名,也可以理解成是对象的引用)

变量作用域

全局变量

属性(成员变量),可以被本类或其他类使用

可以加访问修饰符

有默认值,可以不赋值直接使用

生命周期长,伴随着对象的创建而创建,销毁而销毁

局部变量

不可加修饰符

没有默认值,需要赋值使用

生命周期短,伴随代码块执行而创建,结束而销毁

块级作用域

static静态代码块(最先执行)、构造代码块、方法代码块、局部代码块、语句代码块

属性和局部变量可以重名,优先使用局部变量,在同一个作用域中两个局部变量不能重名

this

  • 代表当前对象,打印对象的 hashCode,哪个对象调用方法,this 就指哪个对象

  • this 用于区分当前对象的属性和局部变量

  • this 不能在类外部使用,只能在类内部实例方法中使用,静态方法不可使用

  • 类内部赋值和获取实例属性

类内部调用方法

方法名(实参列表)

​ this.方法名(实参列表)

1
2
3
4
5
6
7
8
void test(){
System.out.println("this:"+this.hashCode());
}
void test1(){
this.test();
System.out.println("this:"+this.hashCode());
}

this方法

this(实参列表)

1
2
3
4
5
6
7
8
9
10
public Cat(String name){
this(name,30); //必须放在第一行才能使用
this.name=name;
System.out.println(this.name);
System.out.println("this"+this.hashCode());
}
public Cat(String dname,int age){
this.age=age;
System.out.println("Cat(String dname,int agr)");
}

作用

区分相同名字类,方便管理,控制访问范围

建包

建立不同的文件夹/目录来保存类文件

打包

基本语法

1
2
3
package com.butterfly.app
package //关键字
com.butterfly.app //包名

package 的作用是声明当前类所在的包,一个类只能有一个 package

导包

import 指令位置放在 package 下,在类定义前面,可以有多句且没有顺序要求

1
2
3
import java.util.*;
import java.util.HashMap;
java.lang.* 是基本包,默认引入,不需要再引入

访问修饰符

控制属性和方法的访问权限

修饰类的属性,成员方法及类

只有默认的和 public 才能修饰类,并且遵循上述访问权限的特点

本类 同包 子类 不同包
public
protected ×
private × × ×
没有修饰符 × ×

封装

把属性私有,定义公开的 get、set 方法来验证数据合理性

e.g

定义 Account 类,要求具有属性:姓名 name(长度为2-4,初始化后不可修改)、余额 balance(必须大于20)、密码 password(必须是六位)。如果不满足,则给出提示信息,并给默认值

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
Account.java
public class Account {
private String name=null;
private double balance=0;
private String password=null;

public String getName() {
return name;
}

public void setName(String name) {
if(name==null){
System.out.println("名字不能设置为null");
return;
}
if(this.name!=null){
System.out.println("名字只能修改一次");
}else {
if (name.length() < 2 || name.length() > 4) {
System.out.println("名字长度需要2-4位");
} else {
this.name = name;
}
}

}

public double getBalance() {
return balance;
}

public void setBalance(double balance) {
if(balance<=20){
System.out.println("余额必须大于20");
}else{
this.balance = balance;
}
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
if(password==null){
System.out.println("password不能设置为null");
return;
}
if(password.length()==6){
this.password = password;
}else{
System.out.println("密码必须是六位");
}
}
}


Hello.java
Account account=new Account();
account.setName("null");
System.out.println(account.getName());
account.setPassword("123456");
System.out.println(account.getPassword());

继承

语法

1
class 子类 extends 父类{}
1
class Student extends Person{}

注意事项

a. 父类/超类/基类

​ 子类/派生类

b. 多个类存在相同的属性和方法时,从中抽象出父类,在父类中定义相同的属性和方法,所有子类不需要再重新定义,只需要通过 extends 声明继承父类就行

c. 子类自动拥有父类的所有属性和方法(受访问修饰符影响)

d. 子类不能访问父类的属性和方法,可以通过父类的公开方法去访问,类似封装

e. 单继承机制,子类最多只能继承一个父类(直接继承),但是可以实现多个接口

f. 所有类都是 Object 的子类

g. 多次继承 查看方法

练习

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
class A{
String name="AA";
private int age=100;
public void test(){
System.out.println("A test");
}
}
class B extends A{
String name="BB";
String java="java";
private int nums=100;
public void demo(){
//super可以访问的成员(属性和方法)
System.out.println(super.name); //AA
super.test(); //A test
//this可以访问的成员
System.out.println(this.java); //java
System.out.println(this.nums); //100
System.out.println(this.name); //BB
//this.demo(); //递归
this.test();
}
}
class C extends B{
String name="CC";
public void test(){
System.out.println("C test");
}
public void show(){
//super访问成员
System.out.println(super.java); //java
System.out.println(super.name); //BB
super.test(); //C test
super.demo();
//this可以访问哪些成员
System.out.println(this.java); //java
System.out.println(this.name); //CC
this.test(); //C test
}
}

父类构造器

创建子类对象时,默认会调用父类的无参构造器 super( );

如果父类没有提供无参构造器,须在子类构造器中用 super 去知道使用父类哪个构造器

1
2
3
super(参数列表);
e.g.
super(name,age,sex);

super() 和 this() 都只能放在构造器第一行,因此不能共存在同一个构造器;

3.父类构造器的调用不限于直接父类,一直往上追溯到 Object 类(顶级父类)

super

用处

a) 子类和父类具有同名属性和方法时,默认使用子类的同名属性和方法。访问父类的属性或方法必须通过 super 来调用

b) super 代表父类对象的引用,用于访问父类对象的属性、方法、构造器

访问父类的属性(受访问修饰符影响)

1
super.属性名;

访问父类的方法(受访问修饰符影响)

1
super.方法名(参数列表);

访问父类的构造器

1
super(参数列表);

方法重写

子类可以重写方法和属性

方法重写特点

  • 也称为方法覆盖

  • 子类方法的名称、参数、与父类完全相同

  • 返回类型和父类一样,或则是父类返回类型的子类,比如父类返回类型是 Object,子类返回方法类型是 String

  • 子类方法不能缩小父类方法的访问权限

重载与重写的区别

重载同一个类,方法名相同,参数类型、个数或顺序不同,与返回值和修饰符无关

重写父类和子类中,方法名、参数相同,子类返回类型与父类一样或者是其子类,子类不能缩小父类的缩小访问范围

代码块

静态代码块

可以定义多个,与静态属性初始化优先级一样,按照定义顺序执行,随着类的加载而执行,只执行一次,执行时机比普通代码块早

1
2
3
4
5
6
static {
System.out.println("abcdef");
}
static {
System.out.println("abcc");
}

普通代码块

可以定义多个,按照定义顺序执行,随着对象创建而执行,提高构造器代码复用性,每次创建对象都会执行

1
2
3
4
5
6
7
class A extends B{
public A(){
//1)super()
//2)调用本类普通代码块
System.out.println("3");
}
}

类什么时候被加载

  • 创建对象实例

  • 创建子对象实例,父类也会被加载

  • 使用类的静态成员时

  • 使用子类静态成员时,父类也会被加载

创建对象时的调用顺序

  1. 父类的静态代码块和静态属性初始化
  2. 子类的静态代码块和静态属性初始化
  3. 父类的普通代码块和普通属性初始化
  4. 父类的构造方法
  5. 子类的普通代码块和普通属性初始化
  6. 子类的构造方法

静态代码块只能调用静态成员,普通代码块可以调用任意成员

执行 new Test();会输出什么

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
class Demo{
Demo(String s){
System.out.println(s);
}
Demo(){
System.out.println("Demo无参");
}
}
class Test{
Demo demo1=new Demo("Demo1初始化"); //第三步
static Demo demo2=new Demo("Demo2初始化"); //第一步
static {
System.out.println("static执行"); //第二步
if(demo2==null)
System.out.println("demo2 is null");
}
Test(){
System.out.println("Test无参"); //最后一步
}
}
输出:
Demo2初始化
static执行
Demo1初始化
Test无参

多态

多态参数

参数定义成父类类型,就可以传任意子类类型进去

向上转型

a) 语法:

1
父类类型	引用名=new	子类类型();

b) 父类引用指向子类对象

c) 编译类型看左边,运行类型看右边

d) 可以调用父类中所有成员(受访问修饰符影响)

e)调用的时候,子类有就用子类的成员,没有就找父类(就近原则)

f)不能调用子类中特有成员

注意事项

a)多态的前提:连个对象(类)存在继承关系

b)属性的值看编译类型

c)方法都看运行类型,属性看编译类型

d) instanceof 比较操作符,用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型

e)要调用子类中的特有成员要向上转型

多态数组

数组类型为父类类型,保存实际元素为子类

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
public class Hello {
public static void main(String[] args) throws Exception {
B b=new B();
System.out.println(b.count);
b.display();
A a=b;
System.out.println(a==b);
System.out.println(a.count);
a.display();
}
}
class A{
int count=100;
public void display(){
System.out.println(this.count);
}
}
class B extends A{
int count=200;

@Override
public void display() {
System.out.println(this.count);
}
}
输出:
200
200
true
100
200

动态绑定机制

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
public class Hello {
public static void main(String[] args) throws Exception {
A a=new B();
System.out.println(a.sum());
System.out.println(a.sum1());
}
}
class A{
public int i=10;
public int sum(){
return getI()+10;
}
public int sum1(){
return i+10;
}
public int getI(){
return i;
}
}
class B extends A{
public int i=20;
public int sum(){
return i+10;
}
public int getI(){
return i;
}
public int sum1(){
return i+10;
}
}
输出:30 30

1.当调用对象方法时,该方法会和该对象内存地址/运行类型绑定

2.当调用对象属性时,没有动态绑定机制,就近原则

equals

Object

Object 是所有对象的父类,也就是所有对象都可以使用 Object 里面的方法

1
equals getClass hashCode toString

==

判断基本类型和引用类型

基本类型判断,引用类型判断地址

equals

只能判断引用类型,默认判断地址是否相等

子类一般会重写 equals 方法,判断内容是否相等,比如 Integer、String

1
2
3
4
5
6
7
8
9
10
11
12
13
Person p1=new Person();
p1.name="abc";
Person p2=new Person();
p2.name="abc";
System.out.println(p1==p2); //False
System.out.println(p1.equals(p2)); //False
System.out.println(p1.name.equals(p2.name)); //True
System.out.println(p1.name==p2.name); //True

String s1=new String("a");
String s2=new String("a");
System.out.println(s1==s2); //False
System.out.println(s1.equals(s2)); //True

toString

toString 方法

1
2
3
public String toString(){
retrun getClass().getName()+"@"+Integer.toHexString(hashCode());
}

默认返回:全类名+@+哈希值的十六进制

子类往往重写 toString 方法,用于返回对象的属性信息

直接输出一个对象时,toString 方法会被默认调用

finalize 方法

子类重写该方法,释放资源

某个对象没有任何引用时,垃圾回收机制会销毁该对象,销毁前调用 finalize 方法

也可以通过 System.gc() 主动触发垃圾回收机制,但不一定马上回收

final

应用场景

a)不希望类被继承时

b)不希望属性值被修改时(常量)

c)不希望父类的方法被子类覆盖/重写(override)

d)不希望局部变量(参数)被修改(局部变量)

final修饰实例属性,可以在定义时,构造器、普通代码块中赋值

final修饰静态属性,可以在定义时、静态代码块中赋初值

final 注意事项

a)final 修饰属性必须赋值,并且不可修改

b)final 可以修饰类、属性、方法和局部变量,不能修饰构造器

c)包装类(Double、Integer、Float、Boolean )和 String 都是 final 类

d)final 修饰类不能被继承,但能被实例化(需要不被实例化把类改成 private)

e)final 和 static 搭配使用不会加载类

抽象类

abstract 只能修饰类和方法

用 abstract 关键字修饰一个类时,这个类就叫抽象类,修饰方法时就叫抽象方法

注意事项

抽象类可以有任意成员,可以被继承,可以没有抽象方法

抽象类不能被实例化

有了抽象方法,这个类必须声明为 abstract

继承了抽象类,必须实现抽象类的所有抽象方法,除非它自己也声明为 abstract 类

抽象方法不能使用 private、final 和 static 修饰

接口

语法

1
2
3
4
5
6
7
interface 接口名{
//属性
//方法
}
class 类名 implements 接口名{
必须实现接口的所有抽象方法
}

用来制定规则

注意事项

  • 不能被实例化
  • 接口的修饰只能是 public 和默认,这点和类的修饰符是一样的
  • 不能继承其他的类,但可以继承多个别的接口
  • 接口中的方法都是 public 方法,抽象方法可以不用 abstract 修饰,public abstract 可以省略
  • 一个普通类实现接口就必须将该接口的所有方法实现
  • 抽象类实现接口,可以不用实现接口的方法
  • 一个类同时可以实现多个接口
  • 接口中的属性都是 public static final 修饰符

​ 访问形式:接口名. 属性名

接口的多态特性

多态参数、向上转型、多态数组

接口的多态传递

1
2
3
4
5
interface B()
interface A extends B()
class C implements A{}
B b=new C();
A a=new C();

接口、继承

继承:提高代码复用性和可维护性

接口:设计好各种方法,让其他类去实现

练习

1
2
3
4
5
6
7
8
interface AA{int a=23;}
class BB implements AA{}

main函数中:
BB b=new BB();
System.out.println(b.a);
System.out.println(AA.a);
System.out.println(BB.a);

成员内部类

分类

定义在外部类的成员位置上

a)成员内部类(无 static 修饰)

b)静态内部类(使用 static 修饰)

定义在外部类的局部位置上(比如方法类):

a)局部内部类(有类名)

b)匿名内部类(没有类名)

概念

定义在外部类的成员位置上,没有 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
class OuterClass{
public String name="butterfly";
private int age=0;
public static boolean sex=true;
public void test(){}

static {
System.out.println("OuterClass static block");
}
public OuterClass(String name,int age){
this.name=name;
this.age=age;
}
class InnerClass{
public String language="java";
public void abc() {
System.out.println(name);
System.out.println(age);
System.out.println(sex);
test();
}
{
System.out.println("InnerClass block");
}
public InnerClass(String language){
this.language=language;
}
}
}
  • 可以添加任意访问修饰符去修饰成员内部类,因为相当于一个成员
  • 成员内部类不能定义静态成员
  • 作用域与其他成员一样
  • 外部类可以访问成员内部类
  • 外部其他类可以访问成员内部类
1
new Test()..new Inner();

​ 在外部类里面定义一个方法,返回内部类的对象

  • 外部类和内部类重名,就近原则。访问外部类成员,使用(外部类名.this.成员)去访问

获取内部类的类名

getClass、jeb

静态内部类

概念

有 static 修饰

注意事项

  • 只能访问外部类的静态成员,包含私有的

  • 作用域属于整个类

  • 可以添加任意访问修饰符去修饰静态内部类

  • 外部类可以访问静态内部类

  • 外部其他类可以访问静态内部类

    1
    new Test.Inner();

    在外部类里面定义一个方法,返回内部类的对象

    • 外部类和内部类重名,就近原则。访问外部类成员,使用(外部类名.静态成员名)去访问

局部内部类

概念

定义在外部类的局部位置上,比如方法中,并且有类名

注意事项

  • 可以直接访问外部类所有成员
  • 如果定义在静态方法中,只能访问外部类的静态成员
  • 不能添加访问修饰符,可以用final 修饰
  • 作用域仅在代码块中,与局部变量一致
  • 重名遵循就近原则,访问外部类成员用(外部类名.this.成员)去访问(实例方法中),静态方法中,(外部类名.静态成员名)访问
  • 外部类不能访问局部内部类

匿名内部类

语法

基于接口的匿名内部类

基于类(抽象类)的匿名内部类

注意事项

  • 可以访问外部类,受访问修饰符影响,局部内部类不能定义静态成员
  • 只能创建一个实例
  • 就近原则,匿名内部类处于外部类里面时(外部类名.this.成员)静态成员(外部类名.静态类名)
  • 外部类不能访问匿名内部类
  • 匿名内部类在定义的同时直接创建对象,并且当作实参传递

枚举类

自定义枚举类

  • 构造器私有化
  • public static final 修饰的属性
  • 创建对象赋值给这些属性
  • 定义 toString 方法

enum 类

  • 关键字 enum 代替 class

使用关键字 enum 时,会变成 final 类,并且隐式继承 Enum 类

  • javap 反编译 class
  • 不能被继承或再继承其他类,但是可以实现接口
  • 使用 Enum 类相关方法

例子

1
2
3
4
5
6
7
8
9
10
11
Season autumn=Season.AUTUMN;
//name()返回枚举对象的名字
System.out.println(autumn.name());
//ordinal()返回枚举对象的次序/编号,从0开始编号
System.out.println(autumn.ordinal());
//values()返回定义的所有枚举对象
Season[] values=Season.values();
//valueOf()将字符串转换成枚举对象,字符串必须为已有的枚举对象名
Season autumn1=Season valueOf("AUTUMN");
System.out.println(Season.SUMMER.compareTo(SEason.AUTUMN)); //两个值相减
//toString()

注解

Annotation

retrofit2

基本 Annotation

  • @Override:验证方法为重写父类方法,只能用于方法
  • @Deprecated:用于表示某个元素(类/方法等)已过时
  • @SuppressWarnings({“all”}):抑制编译器警告

注解类

  • @Target(ElementType.METHOD),指定注解范围
  • @Target 修饰注解的注释,称为元注解
  • @interface 是注解类

try-catch

try 包裹可能出现异常代码,catch 去捕获异常,try 出现异常,出现异常的代码后面不会执行

throws 与 throw

抛出异常要与父类一致

throw: 后面跟异常对象

throws: 做异常处理方式,在方法中

包装类

包装类型和 String 类型的转换

a) 包装类型转 String 类型

1
2
3
4
5
6
7
Integer i=10;
String s1=i.toString();
String s2=String.valueOf(i);
String s3=i+"";
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);

b)String 类型转包装类型

1
2
3
4
5
6
Integer i1=new Integer(s1);
Integer i2=Integer.valueOf(s2);
Integer i3=Integer.parseInt(s3);
System.out.println(i1);
System.out.println(i2);
System.out.println(i3);

c)例子

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
	Object obj1=true?new Integer(1):new Double(2.0);	//三元条件运算符是一个整体
System.out.println(obj1); //1.0

Object obj2;
if(true){
obj2=new Integer(1);
}else {
obj2=new Double(2.0);
}
System.out.println(obj2); //1


Integer i=new Integer(1);
Integer j=new Integer(1);
System.out.println(i==j); //false

Integer m=1;
Integer n=1;
System.out.println(m==n); //True,指向同一个对象

Integer x=128;
Integer y=128;
System.out.println(x==y); //False超过范围,通过new去创建,不等

Integer a=128;
int b=128;
System.out.println(a==b); //True,存在基本数据类型,比较的是值

字符串

特性

  • final 类,不能被继承
  • 直接赋值,调用构造器
  • 属性 private final char value[ ];存放字符串内容

练习

1
2
3
4
String a="abcd";//指向常量池
String b=new String("abcd");//指向对象,对象指向常量池
System.out.println(a.equals(b)); //True
System.out.println(a==b); //False

常量池字符串

1
2
String s1="hello"+"java";
//hellojava
1
2
3
4
5
6
String a="hell";
String b="jab";
String c=a+b;//new 了一个对象
String d="helljab";
System.out.println(c==d);
//false
1
2
3
4
5
6
7
8
9
10
11
12
String str=new String("abc");
final char[] ch={'j','a','v','a'};
change(str,ch);
System.out.println(str);
System.out.println(ch);
}
public static void change(String str,char ch[]){
str="java";
ch[0]='a';
}

//aava

字符串编码

1
2
3
4
5
String name="我虽然";
String ISO_s=new String(name.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1);
System.out.println(ISO_s);
String UTF8_s= new String(ISO_s.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
System.out.println(UTF8_s);

StringBuffer

特性

  • 不能被继承
  • 父类是 AbstractStringBuilder
  • AbstractStringBuilder 有属性 char[] value,存放在堆中

StingBuffer 和 String 的转换

1
2
3
4
5
6
StringBuffer stringBuffer=new StringBuffer("abcd");
stringBuffer=stringBuffer.append("ac")
String s=stringBuffer.toString();
String ss=new String(stringBuffer);
System.out.println(s);
//abcdac

方法

append,toString

String、StringBuffer、StringBuider

StringBuider 效率最高,拼接字符串

Arrays

sort 方法

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
		Person abc=new Person("abc",30);
Person umr=new Person("umr",23);
Person acd=new Person("acd",40);
Person[] aaa=new Person[]{abc,umr,acd};
Arrays.sort(aaa, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
int i = ((Person)o1) .age -((Person)o2).age;
return i;
}
});
System.out.println(Arrays.toString(aaa));
}
}
class Person{
String name=null;
public int age=0;
public Person(String name,int age){
this.name=name;
this.age=age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

//[Person{name='umr', age=23}, Person{name='abc', age=30}, Person{name='acd', age=40}]

静态方法

Arrays.toString 返回数组的字符串形式

1
2
3
4
5
6
7
8
9
10
Integer[] aa = new Integer[]{4, 2, 3, 1, 5, 6};
Arrays.sort(aa, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
int i = (Integer) o1 - (Integer) o2;
return i;
}
});
System.out.println(Arrays.toString(aa));
//[1, 2, 3, 4, 5, 6]

Arrays.sort 自然排序和定制排序(数值排序、对象排序)

1
参考前面的 sort 方法例子

Arrays.copyOf 数组元素的复制

1
2
3
4
int[] aa=new int[]{0,3,4,6,7,8,9,0,2,5,11,12,13,14};
int[] bb=Arrays.copyOf(aa,aa.length);
bb[0]=1;
System.out.println(Arrays.toString(bb));

Arrays.aslist 数组转化为 List 集合

Arrays.fill 数组填充

Arrays.binarySearch 二分查找(有序数组)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int[] aa=new int[]{0,3,4,6,7,8,9,0,2,5,11,12,13,14};
int i = Arrays.binarySearch(aa,11);
System.out.println(i);
// 10
前提:有序情况下

无序时,先排序
int[] aa=new int[]{0,3,4,6,7,8,9,0,2,5,11,12,13,14};
Arrays.sort(aa);
System.out.println(Arrays.toString(aa));
int i = Arrays.binarySearch(aa,2);
System.out.println(i);
//[0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14]
//2

找不到就返回负数,-(low+1),low 为原本出现的位置,比如查找 10,返回 -11

System.arraycopy 复制数组

System. currentTimeMillens( ) 返回当前距离时间

BigInteger

保存比较大的数

BigDecimal 保存精度更高的小数

  • add 加
  • subtract 减
  • multiply 乘
  • divide 除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
BigInteger bigInteger1=new BigInteger("111111111111111111111111111111111111111");
BigInteger bigInteger2=new BigInteger("100");

BigInteger add=bigInteger1.add(bigInteger2);
System.out.println(add);

BigInteger subtract=bigInteger1.subtract(bigInteger2);
System.out.println(subtract);

BigInteger multiply=bigInteger1.multiply(bigInteger2);
System.out.println(multiply);

BigInteger divide=bigInteger1.divide(bigInteger2);
System.out.println(divide);

集合

集合框架体系

  • 主要是两组 Collection 和 Map (单列集合,双列集合)
  • Collection 接口有两个子接口 List、Set,其实现子类都是单列集合
  • Map 接口的实现子类是双列集合,存放的 K-V

Collection 接口

  • add 添加单个元素,都是Object ,基本数据类型加入的是包装类型

    1
    2
    3
    4
    5
    6
    Collection collection=new ArrayList();
    collection.add(100);
    collection.add("java");
    collection.add(false);
    collection.add(null);
    System.out.println(collection);
  • remove 删除指定元素,List 的子类有重载,可以按 index 删除

  • contains 查找元素是否存在

    1
    2
    collection.contains(false);
    System.out.println(collection.contains(false));
  • size 获取元素个数

  • isEmpty 判断是否为空

  • clear 清空

  • addAll 查找多个元素是否存在

  • removeAll 删除多个元素

List

  • 有序,可重复
  • void add ( int index,Object ele ) 在 index 位置插入 ele 元素
  • boolean addAll ( int index,Collection eles) 从 index 位置开始将 eles 中的所有元素添加进来
  • Object get ( int index) 获取指定 index 位置的元素
  • int indexOf(Object obj)返回 obj 在当前集合中最后一次出现的位置
  • Object remove ( int index) 移除指定 index 位置的元素,并返回此元素
  • Object set ( int index,Object ele ) 设置指定 index 位置的元素为 ele,相当于替换
  • List sublist ( int fromIndex,int toIndex) 返回从 fromIndex 到 toIndex 位置的子集合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
List list =new ArrayList();
list.add("javass");
list.add("urm");
list.add("rr");
list.add(2,"java");

List list2=new ArrayList();
list2.add("javass2");
list2.add("urm2");
list2.add("rr2");
list.addAll(1,list2);
list.add("urm2");
list.add("urm");

System.out.println(list.get(4)); //urm

System.out.println(list.indexOf("urm2")); //2

System.out.println(list.lastIndexOf("urm")); //8
list.remove(8);
list.set(7,"urm4");
System.out.println(list.subList(1,4)); //[javass2, urm2, rr2]
System.out.println(list); //[javass, javass2, urm2, rr2, urm, java, rr, urm4]

List 遍历

  • 适用于所有实现子类

迭代器遍历

  • Iterator 对象为迭代器,用于遍历 Collection 集合的元素

  • 实现 Collection 接口的集合类都有 iterator( ) 方法,返回一个迭代器

  • Iterator 结构

  • Iterator 仅用于遍历集合,Iterator 本身并不存放对象

  • 快捷输入 itit

    1
    2
    3
    4
    5
    6
    7
    8
    9
    	Iterator iterator=list.iterator();
    Object next=iterator.next();
    System.out.println(next); //javass

    Object next2=iterator.next();
    System.out.println(next2); //javass2

    System.out.println(list); //[javass, javass2, urm2, rr2, urm, java, rr, urm2, urm]
    //相当于指针

增强 for 循环

  • 实际上还是迭代器遍历
  • 快捷输入 iter/xxx.for
1
2
3
4
5
6
7
8
9
10
11
12
13
for (Object o : list) {
System.out.println(o);
}

//javass
javass2
urm2
rr2
urm
java
rr
urm2
urm

for 循环

  • xxx.for
  • 前提有索引
1
2
3
4
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
//有索引

ArrayList

  • 由数组实现数据存储
  • Vector 和 ArrayList 基本相同,Vector 线程安全,ArrayList 执行效率高

ArrayList 扩容机制

  • 有一个 Object 类型的数组 elementData,存放元素 transient Object [ ] elementData
  • 指定大小构造器

Vector

  • 对象数组存放元素,protected Object [ ] elementData
  • 指定扩容个数 new Vector(10,3)

LinkedList

  • 双向链表,有两个属性 first 和 last 分别指向首节点和尾节点
  • 每个节点(Node 对象)里面有 prev 、next、item三个属性,item 存放元素,prev 指向前一个节点,next 指向后一个节点
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
	   Node java= new Node("java");
Node rw=new Node("rw");
Node urm=new Node("urm");
java.next=rw;
rw.next=urm;

urm.prev=rw;
rw.prev=java;

Node first=java;
Node last=urm;

Node temp=first;
while(temp!=null){
System.out.println(temp);
temp=temp.next;
}

temp=last;
while(temp!=null){
System.out.println(temp);
temp=temp.prev;
}

}

}
class Node{
public Node prev;
public Node next;
public Object item;

public Node(Object item) {
this.item = item;
}

@Override
public String toString() {
return "Node{" +
"item=" + item +
'}';
}
}
//Node{item=java}
Node{item=rw}
Node{item=urm}
Node{item=urm}
Node{item=rw}
Node{item=java}

Set

  • 无序,没有索引,但是输出顺序固定

    1
    2
    3
    4
    5
    6
    7
    8
    	HashSet hashSet=new HashSet();
    hashSet.add("java");
    hashSet.add("abc");
    hashSet.add("def");
    hashSet.add("javsdv");
    hashSet.add("rw");
    System.out.println(hashSet);
    //[java, abc, def, rw, javsdv]
  • 不允许重复元素,最多包含一个 null

  • Set 接口是 Collection 子接口,常用方法和 Collection 一样

  • Set 接口遍历方式

    • 迭代器遍历
    • 增强 for 遍历
    • 不能用索引来获取,无法使用普通 for 遍历

HashSet

  • 实际上是 HashMap

  • 无序,取决于 hash 后,确定索引结果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     	HashSet set=new HashSet();
    System.out.println(set.add("java"));
    System.out.println(set.add("abc"));
    System.out.println(set.add("def"));
    System.out.println(set.add("java"));
    System.out.println(set.add(null));
    set.remove("def");
    System.out.println("set"+set);
    //true
    true
    true
    false
    truej
    set[null, java, abc]

add 进行的操作

  • HashMap 底层是(数组 + 链表 + 红黑树)
  • 添加一个元素时,先得到 hash 值,然后转化为索引值
  • 找到存储数据表 table ,看这个索引位置是否已经存放元素,没有就直接加入,有就调用 equals 比较,相同就放弃添加,不同就添加到最后
  • 如果一条链表元素个数>=8,table >=64,进行树华
  • 如果链表没达到 8 ,table 没到 64,先进行数组扩容
  • 加入 HashMap 中的元素,是否相同由 HashCode 和 equals 方法决定

LinkedHashSet

  • 不允许添加重复元素,是HashSet子类,底层是 LinkedHashMap
  • 遍历顺序和添加顺序一致
  • 存放元素方式和 HashSet 相同,在此基础上又维护了一个双向链表

Map 接口

  • 与 Collection 并列存在。用于保存具有映射关系的数据:Key - Value (双列集合)
  • key 和 value 可以是任何引用数据类型,会封装到 HashMap$Node 对象中
  • key 不能重复,key 一样时,新的值会替换旧的,value可以重复
  • key 可以为 null (只能一个),value 可以为 null (可以多个)
  • key 和 value 为单向一对一关系,通过指定 key 可以找到对应的 value
1
2
3
4
5
6
7
8
  	Map hashMap=new HashMap();
hashMap.put("user","bb");
hashMap.put("pass","word");
Integer integer=new Integer(100);
hashMap.put(integer,null);

System.out.println(hashMap);
//{100=null, pass=word, user=bb}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	Map hashMap=new HashMap();
hashMap.put("user","bb");
hashMap.put("pass","word");
hashMap.put("admin","me");
Integer integer=new Integer(100);
hashMap.put(integer,null);
hashMap.remove("user");
System.out.println(hashMap.get("pass"));
System.out.println(hashMap.size());
System.out.println(hashMap.isEmpty());
System.out.println(hashMap.containsKey("admin"));
System.out.println(hashMap);
//word
3
false
true
{100=null, pass=word, admin=me}

HashMap 遍历

  • 取出所有的 Key ,通过 key 获取 value

    • 加强 for循环

      1
      2
      3
      4
      Set keyset=hashMap.keySet();
      for(Object key:keyset){
      System.out.println(key+"-"+hashMap.get(key));
      }
    • 迭代器遍历

      1
      2
      3
      4
      5
      Iterator iterator=set.iterator();
      while(iterator.hasNext()){
      Object keyset=iterator.next();
      System.out.println(keyset+"-"+hashMap.get(keyset));
      }
      1
      2
      3
      4
      5
      6
      7
       Set keysset =hashMap.keySet();
      keysset.forEach(new Consumer() {
      @Override
      public void accept(Object keyset) {
      System.out.println(keyset+"-"+hashMap.get(keyset));
      }
      });
  • 取出所有的 value

    1
    2
    3
    4
    Collection values=hashMap.values();
    for(Object value:values){
    System.out.println(value);
    }
  • 通过 EntrySet 来获取 K-V

    1
    2
    3
    4
    5
    Set entrySet=hashMap.entrySet();
    for (Object keyset:entrySet){
    Map.Entry entry=(Map.Entry)keyset;
    System.out.println(entry.getKey()+"-"+entry.getValue());
    }
  • Key-Value 存放

  • keySet 和 values 返回类型

    1
    2
    3
    4
    Set set=map.keySet();
    System.out.println(set.getClass());
    Collection values=map.values();
    System.out.println(values.getClass());

Hashtable

  • 存放键值对:K-V
  • 键值不能为 null
  • 使用方法和 HashMap 差不多一样

Properties

  • 继承自 Hashtable 类
  • 用法和 hashmap 一样,键值不能为 null

TreeSet

  • 如果比较结果器为 0 ,数据不会加入到 TreeSet

  • 在构造器中,可以传入一个比较器,指定排序规则

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    TreeSet treeSet=new TreeSet(new Comparator() {
    @Override
    public int compare(Object o1, Object o2) {
    return ((String)o2).compareTo((String)o1);
    }
    });
    treeSet.add("abcd");
    treeSet.add("abc");
    treeSet.add("abd");
    treeSet.add("cbd");
    treeSet.add("ebd");

    System.out.println(treeSet);
    //[ebd, cbd, abd, abcd, abc]

TreeMap

  • 可以传入一个比较器,指定排序规则
  • 如果比较器返回 0 ,则 key 不会加入到 TreeMap,值会替换

Collections 工具类

  • 是一个操作 Set、List 和 Map等集合的工具类,提供一系列静态方法

排序相关

  • reverse ( List ):反转 List 元素的顺序
  • shuffle ( List ) : 随机打乱
  • sort ( List ) : 按升序排序
  • sort (List,Comparator ) : 制定规则进行排序
  • swap ( List,int i,int j ) : 将 i 和 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
26
27
28
29
	ArrayList arrayList=new ArrayList();
arrayList.add(100);
arrayList.add(200);
arrayList.add(300);
arrayList.add(400);
arrayList.add(500);
arrayList.add(600);
arrayList.add(700);
arrayList.add(800);
arrayList.add(900);
System.out.println(arrayList); //[100, 200, 300, 400, 500, 600, 700, 800, 900]

//reverse(List):对 List 元素进行反转
Collections.reverse(arrayList);
System.out.println(arrayList); //[900, 800, 700, 600, 500, 400, 300, 200, 100]

//shuffle(List):对 List 集合元素进行随机打乱
for (int i = 0; i < 5; i++) {
Collections.shuffle(arrayList);
System.out.println(arrayList);
}

//sort(List):按升序排序
Collections.sort(arrayList);
System.out.println(arrayList); //[100, 200, 300, 400, 500, 600, 700, 800, 900]

//swap(List,int,int):将指定 List 集合的 i 处元素和 j 处元素交换
Collections.swap(arrayList,3,5);
System.out.println(arrayList); //[100, 200, 300, 600, 500, 400, 700, 800, 900]

查找和替换

  • Object max / min(Collection / Collecton,Comparator):根据顺序 / 指定规则返回最大 / 小元素

    1
    2
    Object max=Collections.max(arrayList);
    System.out.println(max);
  • int frequency ( collection,Object ) :返回指定元素出现个数

    1
    2
    int frequency=Collections.frequency(arrayList,500);
    System.out.println(frequency);
  • void copy (List dest,List src):将 src 内容复制到 dest 中

    1
    2
    3
    4
    5
    6
    ArrayList new_arrayList=new ArrayList(arrayList.size());
    for (int i = 0; i < arrayList.size(); i++) {
    new_arrayList.add(0);
    }
    Collections.copy(new_arrayList,arrayList);
    System.out.println(new_arrayList);
  • boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换所有旧值

    1
    2
    Collections.replaceAll(new_arrayList,200,1000);
    System.out.println(new_arrayList);

集合的使用和选择

判断需要存储数据类想

  • 一组对象
  • 一组键值对

一组对象(单列):Collection 接口

  • 允许重复:List

    • 增删多:LinkedList (底层是双向链表)
    • 改查多:ArrayList(底层是 Object 类型的可变数组)
  • 不允许重复:Set

    • 无序:HashSet(底层是 HashMap,数组 + 链表 +红黑树)
    • 排序:TreeSet
    • 插入和取出顺序一致:LinkedHashSet(底层是数组 + 双向链表)

一组键值对(双列):Map 接口

  • 键无序:HashMap( 数组 + 链表 + 红黑树 )
  • 键排序:TreeMap
  • 键插入和取出顺序一致:LinkedHashMap
  • 读取文件:Properties

泛型

基本概念

  • public class ArrayList<E>

    ………

    <E>的 E 为泛型,随意表示

  • 带一个或多个类型参数的类或接口

声明

  • interface List<T>{ }
  • class HashMap<K,V>{ }
  • T、K、V 代表表示类型

泛型实例化

  • HashMap<String,String> hashMap = new HashMap<>( );
  • Iterator<Map.Entry<String,String>> iterator = entries.iterator( );
1
HashMap hashMap=new HashMap();等价于 HashMap<Object> hashMap=new HashMap<>();

自定义泛型类

  • 不指定类型默认为 Object

自定义泛型接口

  • 接口中静态成员不能使用泛型
  • 类型在继承接口或类实现接口时确定

自定义泛型方法

  • 带类型参数的方法

  • 泛型方法可以定义在泛型和普通类里面。使用泛型的方法未定义泛型

  • 可以使用自己声明的泛型,也可以使用类声明的泛型

  • 在调用时会确定类型

泛型通配符 “ ?”

  • 泛型没有继承

    1
    List<Object> list=new ArrayList<String>();
  • <?> : 支持任意泛型类型,任何类型的 List 对象

  • <? extends A> : 接受 A 或 A 的子类,规定上限

  • <? super A> : A 类或 A 的父类,规定下限

反射

  • 在不修改源码时,控制程序,不知道类结构情况下获取类的结构信息
  • 可以突破访问修饰符的限制

Class 类的方法

方法名 作用描述
getName 获取全类名
getSimpleName 获取简单类名
getSuperClass 以 Class 形式返回父类信息
getInterface 以 Class [ ] 形式返回接口信息
getFiled / getFields 获取 public 修饰的字段,包含本类和父类
getDeclaredFiled / getDeclaredFileds 获取本类所有字段
getMethod / getMethods 获取 public 修饰的方法,包含本类和父类
getDeclaredMethod / getDeclaredMethods 获取本类所有方法(包括私有)
getConstructors 获取本类 public 修饰的构造器
getDeclearedConstructors 获取本类所有构造器
getPackage 以 Package 形式返回包信息
getAnnotations 以 Annotation 形式返回注解信息
getClass 得到运行类型
newInstance 创建对象
getClassLoader 得到类加载器
forName 得到类对象

Class 类对象获取方式

  • Class.forName ( … )
  • 类.class 用于参数传递
  • 对象.getClass ( )
  • ClassLoader.loadClass ( … )
  • 基本数据类型的 Class 类对象获取 int.class Integer.TYPE
  • 基本数据类型的 Class 类对象获取 Integer.class

Class 类对象

  • 外部类
  • 成员内部类,静态内部类,局部内部类,匿名内部类
  • interface:接口
  • 数组
  • enum:枚举 Thread.State
  • annotation:注解
  • 基本数据类型
  • void

Class 类的方法

反射创造对象

  • 无参构造器
  • 有参构造器
  • 私有构造器

反射操作属性

  • 获取属性
  • 设置属性
  • 私有属性
  • 如果是静态属性,第一个参数可以给 null

反射操作方法

  • 获取方法
    • getMethod

其他方法

java . lang . reflect .Filed 类

  • getModifiers :以 int 形式返回修饰符
  • getType:以 Class 形式返回类型
  • getName:返回属性名

java . lang . reflect . Method 类

  • getModifiers :以 int 形式返回修饰符
  • getReturnType:以 Class 形式获取返回类型
  • getName:返回方法名
  • getParameterTypes:以 Class [ ] 返回参数类型数组

java . lang . reflect . Constructor 类

  • getModifiers :以 int 形式返回修饰符
  • getName:返回构造器名(全类名)
  • getParameterTypes:以 Class [ ] 返回参数类型数组
  • newInstance

差不多就到这了,笔记比较简洁,里面有很多比较简单的东西没写,可能因为篇幅太长了,传上来的时候老是出现奇奇怪怪的问题,大半夜的差点给我干破防 qwq,搞了好半天才弄好呜呜呜呜呜……


Java 基础
http://example.com/2024/11/09/Java/
作者
butt3rf1y
发布于
2024年11月9日
许可协议