Java基础
Java基础
1.java中的注释有三种
1.单行注释 //
2.多行注释 /* */
3.文档注释 /** */
/**
*
*/
2.标识符和关键字
3.数据类型讲解
4.数据类型扩展及面试题讲解
转义字符
5.变量、常量、作用域
1.变量
2.作用域
3.常量
4.变量的命名规范
6.基本运算符
7.包机制
8.JAVADoc生成文档
9.java方法
1.方法的重载
类+对象+方法
System.out.println();
-
重载就是在一个类中,有相同的函数名称,但形参不同的函数;
-
方法的重载规则:
- 方法名称必须相同;
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)
- 方法的返回类型也可以相同也可以不同
- 仅仅返回类型不同不足以成为方法的重载
-
实现原理
方法名称相同时,汇编器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
2.可变参数
- 从JDK1.5开始,Java支持传递同类型的可变参数给一个方法。
- 在方法声明中,在指定参数类型后加一个省略号(…)。
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。
public static void printMax(double... numbers){
if(numbers.length==0){
System.out.println("No argument passed");
return;
}
double result = numbers[0];
for(int i = 1; i < numbers.length; i++){
if (numbers[i] > result){
result = numbers[i];
}
}
System.out.println("The max value is " + result);
}
123456789101112131415
3.递归
递归就是:A方法调用A方法,就是自己调用自己。
递归结构包括两个部分:
-
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
-
递归体: 什么时候需要调用自身方法。
public class test {
public static void main(String[] args) {
int n = 4;
System.out.println(fun(n));
}
public static int fun(int n){
if (n == 1){
return 1;
}else {
return fun(n-1)*n;
}
}
}
输出:24
//Java使用栈机制,占用内存较高。
10.数组
1.数组的声明和创建
public class test01 {
public static void main(String[] args) {
int[] nums; //1.声明一个数组
//或者 int nums[]
nums = new int[10]; //2.创建一个数组
//整合一句为 int[] nums = new nums[10];
//3.给数组元素中赋值
int sum = 0;
//获取数组长度 arrays.length
for (int i = 0; i < nums.length; i++) {
nums[i] = i+1;
sum+=nums[i];
}
System.out.println("nums:"+nums[5]);
System.out.println("sum: "+sum);
}
}
输出:
nums:6
sum: 55
- 静态初始化
//静态初始化:创建 + 赋值
int[] a = {1,2,3,4,5};
System.out.println("a:"+a[3]);
- 动态初始化
//动态初始化:包含默认初始化
int[] b = new int[10];
b[0] = 10;
2.数组的使用
//for-each循环
int[] nums = {1,2,3,4,5};
//jdk1.5,没有下标
for(int num : nums){
System.out.println(num);
}
//数组作方法入参
public class foreach {
public static void main(String[] args) {
int[] nums = {1,2,3,4,5};
printArray(nums);
}
//打印数组元素
public static void printArray(int[] arrays){
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i]+" ");
}
}
}
//数组作返回值
3.二维数组
public static void main(String[] args) {
int[][] arrays = {{1,2},{2,5},{4,3}};
System.out.println(arrays[0][1]); //2
for (int i=0;i<arrays.length;i++){
for (int j=0;j<arrays[i].length;j++){
System.out.print(arrays[i][j]+" ");
}
System.out.println(" ");
}
输出:
1 2
2 5
4 3
}
4.冒泡排序
import java.util.Arrays;
public class Demo01
{
// 冒泡排序
public static void main(String[] args)
{
// 1.比较数组中,两个相邻的元素,如果第一个比第二个大,我们就交换他们的位置
// 2.每一次比较,都会产生一个最大或最小的数字
// 3.下一轮,则可以少一次排序
// 4.依次循环,直到结束
int[] arr = {
7, 40, 12, 74, 8, 90
};
System.out.println(arr.length);
int[] a = sort(arr);
System.out.println(Arrays.toString(a));
}
public static int[] sort(int[] array)
{
// 临时变量
int temp = 0;
// 外层循环,判断我们这个要走多少次;
for(int i = 0; i < array.length; i++)
{
boolean flag = false;
// 内层循环,比较判断两个数,如果第一个数比第二个数大,则交换位置
for(int j = 0; j < array.length - 1 - i; j++)
{
if(array[j] > array[j + 1])
{ //如果第一个数大于第二个数,2>1,第二个数放前,第一个数放后。
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
flag = true;
}
}
if(flag == false)
{
break;
}
}
return array;
}
}
5.稀疏数组
-
当一个数组中大部分元素为0,或者为同一值得数组时,可以使用稀疏数组来保存该数组。
-
稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少不同值;
- 把具有不同值得元素和行列及值记录在一个小规模数组中,从而缩小程序的规模;
public class ArrayDemo {
public static void main(String[] args) {
// 创建一个二维数组 11*11 0:没有棋子 1:黑棋子 2:白棋子
int[][] arrays = new int[11][11];
arrays[1][2]=1;
arrays[2][3]=2;
arrays[5][6]=5;
arrays[7][4]=2;
arrays[9][3]=8;
//输出原始的数组
System.out.println("输出原始的数组:");
for (int[] array : arrays) {
for (int anInt : array) {
System.out.print(anInt+" ");
}
System.out.println();
}
System.out.println("==================");
//转换为稀疏数组保存
//获取有效值的个数
int sum = 0;
for (int i = 0; i < arrays.length; i++) {
for (int j = 0; j < arrays.length; j++) {
if (arrays[i][j]!=0){
sum++;
}
}
}
System.out.println("有效的个数:"+sum);
//创建一个稀疏数组的数组
int[][] arrary2 = new int[sum+1][3];
arrary2[0][0]=arrays.length;
arrary2[0][1]=arrays.length;
arrary2[0][2]=sum;
//遍历二维数组,将非零的值,存放稀疏数组中
int count = 0;
for (int i = 0; i < arrays.length; i++) {
for (int j = 0; j < arrays.length; j++) {
if (arrays[i][j]!=0){
count++;
arrary2[count][0]=i;
arrary2[count][1]=j;
arrary2[count][2]=arrays[i][j];
}
}
}
System.out.println("===================");
System.out.println("输出稀疏数组:");
for (int i = 0; i < arrary2.length; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(arrary2[i][j]+" ");
}
System.out.println();
}
System.out.println("===================");
System.out.println("还原稀疏数组:");
//1.读取稀疏数组,十一行十一列
int[][] array3 = new int[ arrary2[0][0]][ arrary2[0][1]];
// 2.给其中的元素还原它的值
for (int i = 1; i < arrary2.length; i++) {
array3[arrary2[i][0]][arrary2[i][1]]=arrary2[i][2];
}
System.out.println("输出还原的稀疏数组:");
for (int i = 0; i < array3.length; i++) {
for (int j = 0; j < array3.length; j++) {
System.out.print(array3[i][j]+" ");
}
System.out.println();
}
}
}
//输出结果:
输出原始的数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 5 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 2 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 8 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
==================
有效的个数:5
===================
输出稀疏数组:
11 11 5
1 2 1
2 3 2
5 6 5
7 4 2
9 3 8
===================
还原稀疏数组:
输出还原的稀疏数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 5 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 2 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 8 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
11.面向对象
1.什么是面向对象
非静态方法调用
值传递
public class nums {
public static void main(String[] args) {
int a=1;
System.out.println(a); //输出 1
nums.change(a);
System.out.println(a); //输出 1
}
public static void change(int a){
a=10;
}
}
引用传递
public class Demo01 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name); //输出结果为 : null
Demo01.change(person);
System.out.println(person.name); //输出结果为 : jihu
}
public static void change(Person person){
//person是一个对象:指向的 ----> Person person = new Person();这是一个具体的人,可以改变属性!
person.name = "jihu";
}
}
//定义了一个Person类,有一个属性:name
class Person{
String name;
}
2.类与对象的创建
3.构造器
-
类中的构造器也称为构造方法,是在进行创建爱你对象的时候后必须要调用的,并且构造器有以下两个特点:
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
-
作用:
1. new 本质在调用构造方法
2.初始化对象的值
注意点: 定义有参构造之后,如果想使用无参构造,显示的定义一个午餐的构造
4.简单小结类与对象
5.封装
6.继承 (extends)
ctrl+h看类的关系,所有的类都默认的或间接继承Object
7.super详解
super注意点:
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中!
- super和this 不能同时调用构造方法!
Vs this:
代表的对象不同:
this:本身调用者这个对象
super:代表父类 对象的应用
前提
this:没有继承也可以使用
super:只能在继承条件才可以使用
构造方法
this() ;本类的构造
super():父类的构造!
8.方法重写
重写:需要有继承关系,子类重写父类的方法!
1.方法名必须相同
2.参数列表必须相同.
3.修饰符:范围可以扩大但不能缩小: public>Protected>Default>private
4.抛出的异常:范围,可以被缩小,但不能扩大: ClassNotFoundException --> Exception(大)
重写,子类的方法和父类必要一致: 方法体不同!
为什么需要重写:
1.父类的功能,子类不“定需要, 或者不一定满足!
子类重写父类,执行子类方法。
9.多态
多态注意事项:
-
多态是方法的多态,属性没有多态
-
父类和子类,有联系 类型转换异常!ClassCastException!
-
存在条件:继承关系,方法需要重写,父类引用指向子类对象! Father f1 = new Son();
不符合多态:static 方法,属于类,不属于实例;final 常量;private方法。
10.instanceof和类型转换
类型转化:父子之间,子类转换为父类,可能丢失自己本来的一些方法!
1.父类引用指向子类的对象;
2.向上转型(子类转父类),
3.向下(父类转子类),强制转换;
4.方便方法的调用,减少重复的代码。
11.static关键字详解
public class Student extends Person {
private static int age=1; //静态的变量
private double score = 10; //非静态的变量
public void run(){
System.out.println("run---");
}
public static void go(){
System.out.println("--go---");
}
// 执行顺序: 2
{
System.out.println("匿名代码块");
}
// 执行顺序: 1 一起动项目就会先执行 而且只执行一次 可以用来赋初始值
static {
System.out.println("静态代码块");
}
// 3
public Student() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Student s1 = new Student();
System.out.println("=======");
Student s2 = new Student();
System.out.println(s1.score);
System.out.println(s1.age);
System.out.println(Student.age);
// System.out.println(Student.score); //这样会报错 因为score不是静态的变量
go();
new Student().run();
}
}
输出结果:
静态代码块
匿名代码块
构造方法
=======
匿名代码块
构造方法
10.0
1
1
--go---
匿名代码块
构造方法
run---
//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class test2 {
public static void main(String[] args) {
System.out.println(Math.random());
System.out.println(random()); //导入静态包后 就可以省略Math
System.out.println(PI);
}
}
12.抽象类
//abstract 抽象类 : 类 extends: 单继承 (接口可以多继承)
public abstract class Action {
//约束 ~ 有人帮我们实现
//abstract , 抽象方法,只有方法名字,没有方法的实现
public abstract void doSomething();
//抽象类的特点
//1. 不能new这个抽象类,只能靠子类去实现它:约束!
//2. 抽象类中可以写普通的方法
//3. 抽象方法必须在抽象类中
//抽象的抽象: 约束~
}
//抽象类的所有方法,继承了它的子类,都必须要实现它的方法 ~ 除非它也是抽象类
public class A extends Action{
@Override
public void doSomething() {
}
}
13.接口的定义与实现
接口最能体现oop的精髓,对 对象 的抽象。
在Java编程语言中是一个抽象类型,是抽象对象的集合,对象通常以interface关键字来声明。
-
普通类:只有具体实现
-
抽象类:具体实现和规范(抽象方法)共存
-
接口:只有规范,无法自己实现
约束和实现分离->面向接口编程
接口就是规范,定义一组规则,它的本质是契约,制定好之后大家都要遵守。
/**
* 用户接口,需要实现类
* 锻炼抽象的思维
*/
//interface 定义的关键字 , 接口都需要有实现类
public interface UserService {
// 定义的属性默认是静态常量:public static final
int age = 10;
// 定义的方法是公共抽象:public abstract
//接口中所有定义其实都是抽象的
void add(String str);
void delete(String str);
void update(String str);
void query(String str);
}
public interface TimeService {
void timer();
}
特性
- 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
- 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
- 接口中的方法都是公有的。
实现
/**
* 抽象类用继承:extends
* 接口用实现:implements
* 类可以实现接口,需要现实所有方法!
* 利用接口实现伪多继承~
*/
// 类 可以实现接口 implements 接口
//实现了接口的类 ,就必须重写接口中的方法
//利用接口可以实现多继承
public class UserServiceImpl implements UserService,TimeService {
@Override
public void add(String str) {
}
@Override
public void delete(String str) {
}
@Override
public void update(String str) {
}
@Override
public void query(String str) {
}
@Override
public void timer() {
}
}
类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
在实现接口的时候,也要注意一些规则:
- 一个类只能继承一个类,但是能实现多个接口。
- 一个接口能继承另一个接口,这和类之间的继承比较相似。
多继承
- 类不允许多继承
- 接口允许多继承。
接口与类的区别:
- 接口不能用户实例化对象。
- 接口没有构造方法。
- 接口中所有的方法必须是抽象方法。
- 接口不能包含成员变量,除了static和final变量。
- 接口不是被类集成,而是被类实现。
- 接口支持多继承。
- implements可以实现多个接口
- 必须要重写接口中的方法
14.N种内部类
public class Out {
public int a = 10;
public void out(){
System.out.println("外部类....");
}
//成员内部类
class inner{
public void inner(){
System.out.println("内部类....");
}
}
// 可以直接使用外部类的属性/方法
public void getOterId(){
System.out.println("内部类调用外部类属性和方法");
// 创建成员内部类之前肯定要创建外部类对象
// 即使id不是静态变量、out不是静态方法,但创建外部类对象时已经存在。
System.out.println(a);
out();
}
}
public class demoTest {
public static void main(String[] args) {
Out out = new Out();
out.out();
System.out.println(out.a);
Out.inner inner = out.new inner();
inner.inner();
}
}
输出结果为:
外部类....
10
内部类....
12.异常
1.error和exception
Java把异常当做对象来处理,并定义了一个基类Java.lang.Throwable作为所有异常的超类。
Java语言定义了许多异常类在Java.lang标准包中,主要分为Error和Exception两大类。
2.捕获和抛出异常
异常处理五个五个关键字
- try 、catch、finally、throw、throws
package com.jihu.Demo;
public class Exception {
public static void main(String[] args) {
int a= 1;
int b= 0;
// ctrl + alt + t 快捷键可以快速选择抛的异常
try { //try监控区域
System.out.println(a/b);
} catch (Error e) {
System.out.println("error");
}catch (java.lang.Exception e) {
System.out.println("Exception");
}catch (Throwable e) {
System.out.println("Throwable");
}
finally { //处理善后工作 一般用来 关闭资源
System.out.println("finally");
}
}
}
输出结果:
Exception
finally
//throw throws
public class Exception1 {
public static void main(String[] args) {
int a= 1;
int b= 0;
try {
new Exception1().test(a,b);
} catch (ArithmeticException e) {
// e.printStackTrace();
System.out.println("exception");
}
}
// 假设这个方法中,处理不了这个异常。 方法上抛出异常 用throws
public void test(int a,int b) throws ArithmeticException{
if (b == 0){
throw new ArithmeticException(); //主动抛出的异常,一般在方法中使用
}
}
}
3.自定义异常
自定义异常类
public class CustomException extends Exception {
// 传递数字
private int detail;
public CustomException(int detail) {
this.detail = detail;
}
//toString: 打印异常信息
@Override
public String toString() {
return "CustomException{" + detail + '}';
}
}
测试方法test抛出异常throw,再通过throws向外抛出
public class Test {
public static void main(String[] args) {
try {
test(11);
} catch (CustomException e) {
System.out.println("打印自定义异常信息");
System.out.println(e);
}
}
static void test(int a) throws CustomException {
System.out.println("传输一个参数" + a);
if (a > 10) {
// 抛出自定义异常
throw new CustomException(a);
}
System.out.println("ok");
}
}
总结: