1、常量和变量
变量:
a、在类内,方法外定义的变量叫成员变量,会存在默认值
b、在方法内,定义的变量必须要进行初始化操作,不会存在默认值
c、在一行中可以定义多个变量,但是不推荐,每个变量最好单独一行
1 public class Hello {
2 static int d;
3 public static void main(String args []) {
4 System.out.println(d); //第一点,这个在类内的,是有默认值,默认值为0
5 int c;
6 System.out.println(c); //第二点,这个语法编译会报错
7 int a=10, b=20; //第三点,可以通过,但是不推荐,每个变量最好单独一行
8 }
9 }
常量:
java中的常量定义需要用到关键字 final
1 public class Hello {
2 public static void main(String args []) {
3 final byte num = 12;
4 System.out.println(num);
5 }
6 }
2、算术运算符同其他语言
注意:在java中是没有===这个概念,但是在php和javascript中存在全等于
3、基本数据类型的转换
数据类型的转换分为自动转换(隐形转换), 强制转换
注意:a、在进行算术运算操作的时候,必须要求数据类型一致,否则无法操作;
b、在运算过程中,如果两个值的类型不一致,会自动将小的类型转换为大的类型;
c、在运算过程中,如果需要把大的类型转成小的类型,那么就需要进行强制转换;
d、强制转换,会发生精度损失,结果可能不准确;
public class Hello {
public static void main(String args []) {
char a = 'A';
int b = 12;
// char c = a + b; //第一点,在程序编译的时候会报错
int d = a + b; //第二点会自动把a的类型转换成大的类型int
char e = (char)(a + b); //第三点,进行类型的强制转换,注意,如果转换的时候超过了,会进行二进制转换 比如 (byte)300
System.out.println("d的值为" + d);
System.out.println("e的值为"+e);
}
}
4、流程控制语句
流程控制语句主要分为: 顺序结构 ,分支结构, 循环结构;
注意:流程的跳转主要有: continue, break; return;
注意:break只能跳出当前的循环,而return可以跳出全部的循环;
public class Hello {
public static void main(String args []) {
byte a = (byte)(Math.random() * 6); //生成0-5之间的随机数
if(a > 3) {
System.out.println("结果大于3" + a);
} else {
System.out.println("结果小于3" + a);
}
}
}
小知识点:
java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入。
import java.util.Scanner;
public class Hello {
public static void main(String args []) {
System.out.println("请输入用户名");
Scanner scan = new Scanner(System.in);
if(scan.hasNextLine()) { //判断用户是否有输入
String username = scan.nextLine(); //获取用户输入的内容,并且存储起来
System.out.println("用户名为:\t"+ username); //输出用户输入的内容
}
scan.close();
}
}
switch
import java.util.Scanner;
public class Hello {
public static void main (String args[]) {
System.out.println("请输入一个数字");
Scanner scan = new Scanner(System.in);
if(scan.hasNextInt()) {
int num = scan.nextInt();
switch(num) { //注意第1,2,3的处理结果是一样的,所以可以像以下的方式书写
case 1:
case 2:
case 3:
System.out.println("这是一个小于或等于3的数值:" + num); break;
case 4:
System.out.println("这个数值的值是:" + num); break;
default:
System.out.println("没有在预测范围内" + num); break;
}
}
scan.close();
}
}
switch的新特性
public class Hello { public static void main(String arg[]) { int a = 12; switch(a) { case 10 -> System.out.println(10); case 11 -> System.out.println(11); case 12 -> System.out.println(12); default -> System.out.println("other"); } } }
while
public class Hello {
public static void main(String arg[]) {
int i = 0;
while(i < 100) {
System.out.println("第"+ i + "个数是" + i);
i ++;
}
}
}
for
public class Hello {
public static void main(String arg[]) {
int i = 0;
while(i < 100) {
System.out.println("第"+ i + "个数是" + i);
i ++;
}
}
}
注意:for的好处,相对于while来说,for循环的作用域只存在于括号内,而while是存在于整个方法内部
5、java内,方法的调用
public class Hello { static int count = 12; public static void main(String arg[]) { String str = getName(); System.out.println(str); System.out.println(count); } public static String getName () { return "this is test"; } }
6、java的数组
定义: 数组是相同类型的有序集合
java的数组和javascript中的数组一样,是引用类型
数组的声明方式
public class Hello {
public static void main(String[] arg) {
//方式一 声明并申请空间
int[] a = new int[5];
//方式二 声明数组并赋值,以下的例子数组的长度只有5位
int[] b = new int[]{1, 2, 3, 4, 5};
//方式三 直接初始化,这样数组只有3位
int[] c = {1, 2, 3};
//方式四 定义数组,但不指定长度
int[] d = new int[];
//字符串数组
String[] f = new String[3];
f[0] = "this is test";
//布尔数组
boolean[] g = new boolean[2];
System.out.println(d[0]);
}
}
数组的遍历
public class Hello {
public static void main(String[] arg) {
//数组的遍历 方式一
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println(sum);
//数组的遍历 方式二
int[] arr1 = new int[]{1, 1, 2, 2, 3, 3, 4, 4};
int total = 0;
for(int i: arr1) {
total += i;
}
System.out.println(total);
}
}
注意:数组是引用类型,当创建完成数组之后相当于是在方法外定义了一个变量,此时数组中的值是有默认值的,默认值是什么,取决于你定义的数组的类型 int => 0 string => null boolean => false
冒泡排序方法
import java.util.Arrays;
public class Hello {
public static void main(String[] arg) {
int[] arr = new int[]{1, 3, 6, 4, 2, 8, 0, 7, 9, 5};
for(int i = 0; i < arr.length; i ++) {
for(int j = 0; j < arr.length - 1 - i; j ++) {
if(arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
二维数组的定义
public class Hello {
public static void main(String[] arg) {
//方式一
int[][] arr1 = new int[3][4]; // arr1里面包含3个数组 每个数组里面有四个元素
//方式二
int[][] arr2 = new int[3][]; //第二种方式和第一种类似,只是数组中每个元素的长度不确定
//方式三
int[][] arr3 = {{1,2},{3,4,5,6},{7,8,9}}; //二维数组中定义了三个元素,这三个元素都是数组,分别为{1,2}、{3,4,5,6}、{7,8,9}
}
}
注意:以上的 int[][]是表示类型
7、java类的学习
import java.util.Scanner;
public class Hello {
private String username = "admin";
private String password = "123456";
private Scanner scan = new Scanner(System.in);
/**
* 获取输入的内容
* @param tip
* @return
*/
private String getInputContent(String tip) {
System.out.println(tip);
String content = this.scan.hasNextLine()? this.scan.nextLine(): null;
return content;
}
/**
* 进行值的比较
* @param val
* @param target
* @return
*/
private boolean compareVal(String val, String target) {
return val.equals(target);
}
/**
* 判断字符串是否为空
* @param str
* @return
*/
private boolean checkIsNull(String str) {
return str == null || str.equals("");
}
/**
* 对外暴露接口检查信息
* @return
*/
public boolean checkInfo() {
String inputName = this.getInputContent("请输入用户名");
String inputPass = this.getInputContent("请输入密码");
return this.compareVal(inputName, this.username) && this.compareVal(inputPass, this.password);
}
/**
* 变更信息
*/
public void changeInfo() {
String tempName = this.getInputContent("请输入新的用户名");
String tempPass = this.getInputContent("请输入新的密码");
if(this.checkIsNull(tempName) || this.checkIsNull(tempPass)) {
System.out.println("密码修改不成功,用户名或者密码不能为空,请重新修改");
} else {
this.username = tempName;
this.password = tempPass;
System.out.println("用户名是" + this.username + "密码是" + this.password);
this.scan.close();
}
}
public static void main(String[] args) {
Hello test = new Hello();
while(true) {
boolean sign = test.checkInfo();
if(sign) {
test.changeInfo();
break;
} else {
System.out.println("用户名或者密码发生错误,请重新输入");
}
}
}
}
特别注意: 在判断两个字符串是否相等的时候不能用 == ,因为在java中String类型不是基本类型,而是引用类型,如果用==那么比较的的是引用的址址,而不是值是否相等,所以要用equals进行比较,而数值是基本类型,所以可以用==进行比较。java中除了基本类型外都是引用类型
类的构造方法
在java中的构造方法的名称是和类名一致的
注意:
1、创建完类后,如果没有手动调用构造方法,会有一个默认的无参的构造方法供调用
2、当用户自定义了构造方法之后,默认的无参构造方法就不能够使用了,必须手动定义无参构造方法
3、同一个类中可以包含多个构造方法(但参数需不一致, 相当于函数重载)
函数的重载:可以定义多个同名方法的条件
1、参数的个数不一致
2、参数的类型不一致
3、参数的顺序不一致
public class Teacher {
private String name;
private byte age;
/**
* 构造函数一
* @param name
* @param age
*/
public Teacher (String name, byte age) {
this.name = name;
this.age = age;
}
/**
* 构造函数二
*/
public Teacher () {
this.name = "不知道";
this.age = 0;
}
public void introduce () {
System.out.println("我的名字叫:" + this.name + ", 我今年" + this.age + "岁了");
}
public static void main(String[] args) {
Teacher t1 = new Teacher("小明", (byte) 30);
t1.introduce();
Teacher t2 = new Teacher();
t2.introduce();
}
}
因为在java中的参数不能进行默认设置,也不能设置可选参数,那么就可以进行函数重载解决这个需求, 所以一般的构造方法都会进行重载(因为一个类中可能包含多个属性值,当只需要给部份属性初始化的时候就需要调用不同的构造方法)
public class Teacher {
private String name;
private byte age;
/**
* 构造函数一
* @param name
* @param age
*/
public Teacher (String name, byte age) {
this(name);
this.age = age;
}
/**
* 构造函数二
* @param name
*/
public Teacher (String name) {
this.name = name;
}
public void introduce () {
System.out.println("我的名字叫:" + this.name + ", 我今年" + this.age + "岁了");
}
public static void main(String[] args) {
Teacher t1 = new Teacher("小明", (byte) 30);
t1.introduce();
Teacher t2 = new Teacher("小冬");
t2.introduce();
}
}
注意: 如果一个构造函数需要调用另外一个构造函数, 那么使用的语法是 this(args);如上面的例子。
java静态变量以及方法的调用
public class Teacher {
private String name;
private byte age;
public static String sex = "man";
public Teacher (String name, byte age) {
this.name = name;
this.age = age;
}
public void say () {
System.out.println(this.sex); //静态方法可以通过这种方式调用
}
public static void main(String[] args) {
Teacher t = new Teacher("bill", (byte)30);
System.out.println(t.sex); //调用方法一,此方法不同于js与php
System.out.println(Teacher.sex); //调用方法二
t.say();
}
}
静态变量的变化,不管是方法一的更改还是方法二的更改都会影响该变量的存储
8、java的代码块
代码块:使用{}括起来的一段代码叫做代码块
分类:
a、普通代码块:定义在方法中,使用{}括起来的代码叫做普通代码块。
b、构造代码块:定义在类中使用{}括起来的代码叫做构造代码块
注意: 每次代码运行的时候会将构造代码块中的代码添加到构造方法的前面
构造代码块中的代码会添加到每一个构造方法中,当使用this(参数)的时候不会添加
c、静态代码块:使用static{}括起来的代码叫做静态代码块,在程序载入的时候优先执行 =》 使用在数据库连接等其他需要提前准备好的代码会放在static代码块中 (多次实例化类的时候,只会执行一次, 一般被用来进行static变量的初始化)
d、同步代码块: 在多线程的时候会用,用来给共享空间进行加锁操作
执行的优先顺序: 静态代码块 =》 构造代码块(创建对象的时候会用到) =》 普通代码块
public class Teacher {
public String name;
public int age;
{
System.out.println("这个是构造函数代码块"); //构造函数代码块,会被添加到构造函数的前面
}
static {
System.out.println("这个是静态代码块"); //静态代码块
}
public Teacher (String name, int age) {
this.name = name;
this.age = age;
}
public Teacher () {
this.name = "default";
this.age = 0;
}
public void teach () {
System.out.println("我是一个老师,我的名字是:" + this.name + ", 我今年" + this.age + "岁了");
{
System.out.println("这个是普通代码块"); //普通代码块
}
}
public static void main(String[] args) {
Teacher t = new Teacher("bill", 30);
t.teach();
Teacher t1 = new Teacher();
t1.teach();
}
}
输出的内容:
这个是静态代码块 //只被执行一次 这个是构造函数代码块 我是一个老师,我的名字是:bill, 我今年30岁了 这个是普通代码块 这个是构造函数代码块 我是一个老师,我的名字是:default, 我今年0岁了 这个是普通代码块
9、package
为了解决两个问题:
1、文件的同名问题
2、为了方便管理类,将具体处理功能的代码放到同一目录下
使用:
一般定义package会放置在java文件的第一行
package的命名规则 域名的倒序 + 模块 + 功能 (大小写定一般采用全部小写的规则)
比如 package com.baidu.(模块名或文件名)
完全限定名:包名 + 类名
规则:
根据程序设计的单一职责原则一般来讲,在一个包中,只存储与这个包相关的类
在idea中新建package输入例如com.yfbill.test就会自动创建如下的目录
注意:代码中声明包的位置时必需是处于第一行
package的配置
把上面的这个紧凑中间包的选项去除就可以分层建立package了
手动编译:假如当前在 test目录下,运行 javac -d . Test.java 编译完成后,在src层级的目录下运行 java com.yfbill.test.Test就可以运行了,com.yfbill.test相当于文件夹的层级
10、import 导入包
当需要引入非lang包的其他java类的时候,需要使用import 工具
如不使用import时,每次在使用某个类的时候必须要将类的完全限定名都加上才可以使用,在过于繁琐 如 java.util.Date date = new java.util.Date();
用法:
a、import java.包名.类名; =》这种方法是按需导入,推荐使用
b、import 包名.*; => 这种方法是把指定包名下的所有类全部导入,不推荐使用 例如 import java.util.*;
注意:
当一个java文件中需要使用多个同名的类的时候,只能选择导入一个,另一个使用完全限定名的方式进行导入
package com.yfbill.test;
import java.util.Date;
import java.util.*; //导入全部的包
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date(); //使用完全限定名的方式导入
Date d = new Date(); //使用导入的包的方式
}
}
静态导包
当需要使用某个类的多个方法的时候,同时又不想频繁写该类的名称,此时可以使用静态导包的方式
package com.yfbill.test;
import static java.lang.Math.*; //进行静态导包
public class Test {
public static void main(String[] args) {
//因为lang这个类是系统自动导入的,所以无需再导入
//使用常用的方法进行导入
double num = Math.random();
double count = Math.pow(2, 3);
System.out.println(num);
System.out.println(count);
//使用静态导包的方式进行调用
System.out.println(random());
System.out.println(pow(3,2));
}
}
java类的get和set 方法的使用
package com.yfbill.use;
public class Student {
private String name;
private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}
java中访问修饰符的权限
同一个类 | 同一包中 | 子类 | 所有类 | |
private | * | |||
default(没有修饰符) | * | * | ||
protected | * | * | * | |
public | * | * | * | * |
注意:如果类中没有public那个就默认是default权限与上面的default的使用是一致的
11、java中super关键字
a、super 是直接父类对象的引用(如果是A->B->C->D, 如果D中调用super那么调用的是C里的方法);
b、可以通过super来访问父类中被子类覆盖的方法或属性,用法:super.方法名
c、在构造函数中调用父类的的构造函数,super要放在第一行
d、在构造函数中this()调用本类中的其他构造方法是不能和super同时存在
e、子类的构造方法都会默认调用父类的无参构造方法,除非手动声明super,所以在定义类的时候无论是否自定义了其他构造方法,最好将无参构造方法写上
f、在定义一个类的时候,没有调用extends,则它的父类是: java.lang.Object
12、方法的重写
a、在子类中可以根据需要对基类中继承来的方法进行重写
b、重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型
c、重写方法不能使用比被重写方法更严格的访问权限 比如public就不能重写成protected或private(由于多态)
父类
package com.yfbill.test;
public class Check {
public Check() { }
protected String say() {
return "this is say demo";
}
}
子类
package com.yfbill.test;
public class Test extends Check{
public Test() {}
@Override
public String say() {
return super.say() + " are you ok???";
}
public static void main(String[] args) {
Test t = new Test();
System.out.println(t.say());
}
}
注意:父类的静态方法是可以被继承,但是不能被重写,但是如果需要改变的话,可以在子类中定义一个一样的函数即可
13、抽象类
a、创建抽象类的时候需要添加 abstract 关键字
b、不能进行实例化,也就是不能new对象
c、抽象类中的某些方法需要子类进行更丰富的实现,父类实现没有意义,此时可以将抽象类中的方法定义为抽象方法,没有具体实现,只包含方法名字,返回值,参数列表,访问修饰符
d、使用 abstract 关键字修饰的方法叫做抽象方法,可以不写方法实现
抽象类
package com.yfbill.test;
/**
* 抽象类
*/
public abstract class Check {
public Check() { }
/**
* 抽象方法
* @return
*/
protected abstract String say();
/**
* 抽象类中的普通方法
*/
protected void init() {
System.out.println(this.say());
}
}
继承类
package com.yfbill.test;
public class Test extends Check{
public Test() {}
@Override
protected String say() {
return "are you ok????";
}
public static void main(String[] args) {
Test t = new Test();
t.init();
}
}
14、final的使用
a、final可以修饰变量 =》 表示变量的值不可变
b、final可以修饰方法 =》 表示方法不可以被重写
c、final可以修饰类 =》 表示不可以被继承
package com.yfbill.test;
public final class Test{
public final static String name = "bill";
public final String getName () {
return Test.name;
}
}