步骤清晰简单,第一步做什么,第二步做什么……
适合处理简单问题
物以类聚,分类的思维模式,首先解决问题是需要那些分类。
适合处理复杂问题,如多人协作的问题
对于描述复杂的事物,宏观上需要用面向对象的思路来分析,对于具体的微观操作,仍需要面向过程的思路去处理
面向对象编程(Object-Oriented Programming,OPP)
面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
从认识的角度,先有对象后有类。对象,是具体的事物;类,是抽象的,是对对象的抽象
从代码运行角度,先有类后有对象。类是对象的模板。
类是一种抽象的数据类型,它是对某一类事物的整体描述/定义,但是并不能代表某一个具体事物
对象是抽象概念的具体实例
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
类中的构造器也称为构造方法,是在创建对象的时候必须调用的。并且构造器有以下两个特点:
=> 属性私有(private)并提供一些public的get、set方法
public对外部完全可见。proteced对本包和所有子类可见。private仅对本类可见。默认对本包可见,不需要修饰符。
默认与this使用本类的方法,super使用超类的方法
public void test(){
print();//调用本类的print方法
this.print();//调用本类的print方法
super.print();//调用超类(父类)的print方法
}
调用父类的构造器,必须在构造方法的第一个。
只能在继承条件下才可以使用。
重载 ≠ 重写
重写都是方法的重写,与属性无关
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。
多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
父类的引用指向子类,若子类重写了父类的方法,执行子类的方法
父类型可以指向子类,但是不能调用子类独有的方法
子类型能调用的方法是自己的或继承父类的
abstract 抽象修饰符,可抽象类和方法
类 extends:单继承 (但接口可以多继承)
抽象方法只有方法名字,没有方法的实现
抽象类无法new,只能靠子类去实现它:约束
抽象类中可以写普通的方法
抽象方法必须在抽象类中
声明类的关键字是class,声明接口的关键字是interface
简单代码示例:
// interface 定义的关键字 , 接口都需要有实现类
public interface UserService {
//接口中的所有定义其实都是抽象的 public abstract
void run();
public abstract void run(String name); //public abstract 是灰色的,不用写也是默认该类型
//接口内可以生成常量 public static final
int AGE = 99;
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
public interface TimeService {
void timer();
}
//抽象类:extends
// 类可以实现接口 implement 接口
//实现了接口的 类,就需要 重写 接口中的方法
//多继承 利用接口实现多个继承
public class UserServiceImpl implements UserService,TimeService{
@Override
public void run() {
}
@Override
public void run(String name) {
}
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
作用:
内部类就是在一个类的内部再定义一个类。
内部类代码示例:
public class innerClass {
public static void main(String[] args) {
var clock = new TalkingClock(1000,true);
clock.start();
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit(0);
}
}
class TalkingClock{
private int interval;
private boolean beep;
//alt+insert构造函数,一键构造类构造器
public TalkingClock(int interval, boolean beep) {
this.interval = interval;
this.beep = beep;
}
public void start(){
var listener = new TimePrinter();
var timer = new Timer(interval,listener);
timer.start();
}
public class TimePrinter implements ActionListener{
@Override
public void actionPerformed(ActionEvent event) {
System.out.println("At the tone, the time is" + Instant.ofEpochMilli(event.getWhen()));
if(beep) Toolkit.getDefaultToolkit().beep();
}
}
public void start2(){
//声明局部内部类时不能有访问说明符(即public或private)
// 局部类对外部世界完全隐藏,即使TalkingClock类中的其他代码也不能访问他,除start2外,没有任何方法知道TimePrinter2类的存在
class TimePrinter2 implements ActionListener{
public void actionPerformed(ActionEvent event){
System.out.println("At the tone, the time is" + Instant.ofEpochMilli(event.getWhen()));
if(beep) Toolkit.getDefaultToolkit().beep();
}
}
}
/*
一般的,匿名类语法如下:
new SuperType(construction parameters)
{
inner class methods and data
}
//SuperType 可以是接口也可以是类,如果是接口要实现接口,如果是类需要扩展这个类
//匿名内部类没有类名。因此没有构造器
//内部类实现一个接口,不能有任何构造参数,但依然需要小括号
new InterfaceType(){
methods and data
}
*/
public void start(int interval, boolean beep){
var listener = new ActionListener()//创建一个类的新对象
{
//实现的方法在括号内定义-> 实现了ActionListener接口
public void actionPerformed(ActionEvent event)
{
System.out.println("At the tone, the time is" + Instant.ofEpochMilli(event.getWhen()));
if(beep) Toolkit.getDefaultToolkit().beep();
}
};
var timer = new Timer(interval, listener);
if(beep) Toolkit.getDefaultToolkit().beep();
timer.start();
}
//运用lamda表达式
public void start2(int interval, boolean beep){
var timer = new Timer(interval, event->{
System.out.println("At the tone, the time is" + Instant.ofEpochMilli(event.getWhen()));
if(beep) Toolkit.getDefaultToolkit().beep();
});
timer.start();
}
}
静态内部类代码示例:
public class staticInnerClass {
public static void main(String[] args) {
var values = new double[20];
for(int i = 0; i<values.length; i++)
values[i] = Math.random()*100;
ArrayAlg.Pair p = ArrayAlg.minmax(values);
System.out.println("min = " + p.getFirst());
System.out.println("max = " + p.getSecond());
}
}
//使用内部类最吸引人的原因是:
//每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对内部类都没有影响。
//内部类有效的实现了“多重继承”。也就是说,内部类允许继承多个非接口类型(类或者抽象类)。
//使用内部类还可以获得其他一些特性
//1. 内部类可以有多个实例,每个实例都有自己的状态信息,并且与外围类对象的信息相互独立。
//2. 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。
//3. 创建内部类对象的时刻并不依赖于外围类对象的创建。
//4. 内部类并没有令人迷惑的 “is-a”关系;它就是一个独立的实体。
class ArrayAlg
{
//静态内部类Pair
//为了把一个类隐藏在另一个类的内部,并不需要内部类有外围类对象的一个引用。(不需要外围的信息)
public static class Pair {
private double first;
private double second;
public Pair(double first, double second) {
this.first = first;
this.second = second;
}
public double getFirst() {
return first;
}
public double getSecond() {
return second;
}
}
public static Pair minmax(double[] values)
{
double min = Double.POSITIVE_INFINITY;
double max =Double.NEGATIVE_INFINITY;
for (double v: values)
{
if (min>v) min = v;
if (max<v) max = v;
}
return new Pair(min,max);
}
}
静态代码块首先执行并只运行一次,匿名代码块后执行且每new一个对象就会执行一次,后执行构造方法
public class Person {
public Person(){
System.out.println("构造方法");
}
//第二执行,且能执行多次 => 用于赋初始值 跟对象同时产生
{
System.out.println("匿名代码块");
}
//最早执行且执行一次
static {
System.out.println("静态代码块");
}
public static void main(String[] args) {
Person person1 = new Person();
System.out.println("====================");
Person person2 = new Person();
System.out.println("====================");
Person person3 = new Person();
}
}
/*
输出结果为:
静态代码块
匿名代码块
构造方法
====================
匿名代码块
构造方法
====================
匿名代码块
构造方法
*/
静态导入包补充
//静态导入包
import static java.lang.Math.random;
public class Test {
public static void main(String[] args) {
//若无静态导入包
System.out.println(Math.random());
//静态导入包后可将Math省略
System.out.println(random());
}
}
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Instant;
import javax.swing.*;
public class innerClass {
public static void main(String[] args) {
var clock = new TalkingClock(1000,true);
clock.start();
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit(0);
}
}
class TalkingClock{
private int interval;
private boolean beep;
//alt+insert构造函数,一键构造类构造器
public TalkingClock(int interval, boolean beep) {
this.interval = interval;
this.beep = beep;
}
public void start(){
var listener = new TimePrinter();
var timer = new Timer(interval,listener);
timer.start();
}
public class TimePrinter implements ActionListener{
@Override
public void actionPerformed(ActionEvent event) {
System.out.println("At the tone, the time is" + Instant.ofEpochMilli(event.getWhen()));
if(beep) Toolkit.getDefaultToolkit().beep();
}
}
public void start2(){
//声明局部内部类时不能有访问说明符(即public或private)
// 局部类对外部世界完全隐藏,即使TalkingClock类中的其他代码也不能访问他,除start2外,没有任何方法知道TimePrinter2类的存在
class TimePrinter2 implements ActionListener{
public void actionPerformed(ActionEvent event){
System.out.println("At the tone, the time is" + Instant.ofEpochMilli(event.getWhen()));
if(beep) Toolkit.getDefaultToolkit().beep();
}
}
}
/*
一般的,匿名类语法如下:
new SuperType(construction parameters)
{
inner class methods and data
}
//SuperType 可以是接口也可以是类,如果是接口要实现接口,如果是类需要扩展这个类
//匿名内部类没有类名。因此没有构造器
//内部类实现一个接口,不能有任何构造参数,但依然需要小括号
new InterfaceType(){
methods and data
}
*/
public void start(int interval, boolean beep){
var listener = new ActionListener()//创建一个类的新对象
{
//实现的方法在括号内定义-> 实现了ActionListener接口
public void actionPerformed(ActionEvent event)
{
System.out.println("At the tone, the time is" + Instant.ofEpochMilli(event.getWhen()));
if(beep) Toolkit.getDefaultToolkit().beep();
}
};
var timer = new Timer(interval, listener);
if(beep) Toolkit.getDefaultToolkit().beep();
timer.start();
}
//运用lamda表达式
public void start2(int interval, boolean beep){
var timer = new Timer(interval, event->{
System.out.println("At the tone, the time is" + Instant.ofEpochMilli(event.getWhen()));
if(beep) Toolkit.getDefaultToolkit().beep();
});
timer.start();
}
}
public class staticInnerClass {
public static void main(String[] args) {
var values = new double[20];
for(int i = 0; i<values.length; i++)
values[i] = Math.random()*100;
ArrayAlg.Pair p = ArrayAlg.minmax(values);
System.out.println("min = " + p.getFirst());
System.out.println("max = " + p.getSecond());
}
}
//使用内部类最吸引人的原因是:
//每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对内部类都没有影响。
//内部类有效的实现了“多重继承”。也就是说,内部类允许继承多个非接口类型(类或者抽象类)。
//使用内部类还可以获得其他一些特性
//1. 内部类可以有多个实例,每个实例都有自己的状态信息,并且与外围类对象的信息相互独立。
//2. 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。
//3. 创建内部类对象的时刻并不依赖于外围类对象的创建。
//4. 内部类并没有令人迷惑的 “is-a”关系;它就是一个独立的实体。
class ArrayAlg
{
//静态内部类Pair
//为了把一个类隐藏在另一个类的内部,并不需要内部类有外围类对象的一个引用。(不需要外围的信息)
public static class Pair {
private double first;
private double second;
public Pair(double first, double second) {
this.first = first;
this.second = second;
}
public double getFirst() {
return first;
}
public double getSecond() {
return second;
}
}
public static Pair minmax(double[] values)
{
double min = Double.POSITIVE_INFINITY;
double max =Double.NEGATIVE_INFINITY;
for (double v: values)
{
if (min>v) min = v;
if (max<v) max = v;
}
return new Pair(min,max);
}
}
存放new的对象和数组
可以被所有的线程共享,不会存放别的对象引用
存放基本变量类型(包含这个基本类型的具体数值)
引用对象的变量(会放在这个引用堆的具体地址)
可以被所有线程共享
包含了所有的class和static变量
数组的工具类 java.util.Arrays
Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用(注:是“不用”而不是“不能”)
具有以下功能:
Java方法是语句的集合,它们在一起执行一个功能。
方法的本意是功能块,是实现某个功能的语句块的集合。设计方法时,最好保持原子性,即一个方法只完成一个功能,有利于后期的拓展。
首字母小写驼峰原则
public class Demo01 {
//main 方法
public static void main(String[] args) {
int sum = add(1,2);
System.out.println(sum);
}
//加法 add 方法
public static int add(int a, int b){
return a+b;
}
}
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;//void 无须return。返回时要符合返回值类型。
}
调用方法:对象名.方法名(实参列表)
Java支持两种调用方法的方式,根据方法是否返回值来选择。
int larger = max(30,40);
System.out.println("xxx");
Java都是值传递
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如匹配失败,则报错。
public class Demo01 {
//main 方法
public static void main(String[] args) {
int sum = add(1,2);
System.out.println(sum);//输出3
double sum2 = add(1.0,5.0);
System.out.println(sum2);//输出6.0
}
//加法 add 方法
public static int add(int a, int b){
return a+b;
}
//加法 add 方法
public static double add(double a, double b){
return a+b;
}
}
在运行一个程序时在传递给它消息。依靠传递命令行参数给main()函数实现。
在方法声明中,在指定参数类型后加一个省略号。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
public class Demo03 {
public static void main(String[] args) {
Demo03 demo03 = new Demo03();
demo03.test(4,5,7,9,5,78);
}
public void test(int x,int ...i){
System.out.println(x);
System.out.println(i[0]);
System.out.println(i[2]);
System.out.println(i[3]);
}
}
包:java.util.Scanner
通过Scanner类来获取用户的输入
基本语法:
Scanner s = new Scanner(System.in)
//IO流的类如果不关闭会一直占用资源
//养成用完就关掉的习惯
scanner.close();
简单Scanner程序:
import java.util.Scanner;
public class Demo02 {
public static void main(String[] args) {
//创建一个扫描器对象,接受键盘数据
Scanner scanner = new Scanner(System.in);
double sum = 0;
int m = 0;
System.out.println("请输入任意个数字,并以任意字符结束");
//通过while循环判断是否还有输入,并进行统计
//scanner.hasNext... 判断是否有...输入
while (scanner.hasNextDouble()){
double x = scanner.nextDouble();
m++;
sum +=x;
}
System.out.println("和为:"+sum);
//IO流的类如果不关闭会一直占用资源
//养成用完就关掉的习惯
scanner.close();
}
}
除非特别指明,否则就按照顺序一句一句执行。
基本算法结构。
if(condition) statement
if(condition) statement1 else statement2
一条指令成功执行,直接跳过剩下未判断的语句,跳出if结构
if(condition) statement1
else if(condition) statement2
else if(condition) statement3
.
.
.
else statementn
if(condition){
statement1;
if(condition){
statement2
//……
}
}
case具有穿透现象,如果case内无break会继续向下执行。
switch语句中的变量可以是byte、short、int、char或String
switch(expression){
case value1:
statement1;
break;//可选
case value2:
statement2;
break;//可选
case value3:
statement3;
break;//可选
//……
default:
statementn;
}
while(condition) statement
当条件为true时,while循环执行一条语句(或一块语句)。
如果开始时循环条件的值就位false,那么while循环一次也不执行。
除非特定需要,避免造成死循环。
do statement while(condition)
这种循环语句先执行语句,然后再检测循环条件。如果为true,就重复执行语句,然后再次检测循环条件。
for(初始化;condition;更新)
statement;
简单for循环程序
public class Demo01 {
public static void main(String[] args) {
//初始化//条件判断//迭代
for(int i = 1; i <= 10; i++){
System.out.println(i);
}
}
}
可以依次处理数组(或者其他元素集合)中的每个元素,而不必考虑指定下标值。
for(variable : collection) statement
for each 输出二维数组
public class Demo02 {
public static void main(String[] args) {
double [][] a = new double [3][4];
for (int i = 0; i<a.length; i++){
for (int j = 0; j<a[i].length; j++){
a[i][j] = Math.random()*100;
a[i][j] = (double)Math.round(a[i][j]*100)/100;
}
}
//for each 输出二维数组
for(double[] row : a) {
for (double value : row) {
//do something with value
System.out.print(value+"\t");
}
System.out.println();
}
//快速输出二维数组的元素列表
System.out.println(Arrays.deepToString(a));
}
}
在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。
用在循环语句体中,用于终止某次循环过程,跳过循环体中未执行的语句,接着进行下一次是否执行循环的判断。
注释并不会被执行,是给人看的
其注释内容从 // 开始到本行结尾
public class helloworld {
public static void main(String[] args) {
//这是注释
/* 这也是
注释
*/
System.out.println("Hello world!");
}
}
javadoc 命令是用来生成自己API文档的
- 参数信息
- @author 作者名
- @version 版本号
- @since 指明需要最早使用的jdk版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
/**
* This is the first sample program
* @version 11
* @author Tagiri
*/
/**
* ░░░░░░░░░░░░░░░░░░░░░░░░▄░░
* ░░░░░░░░░▐█░░░░░░░░░░░▄▀▒▌░
* ░░░░░░░░▐▀▒█░░░░░░░░▄▀▒▒▒▐
* ░░░░░░░▐▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒▐
* ░░░░░▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒▐
* ░░░▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌
* ░░▐▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒
* ░░▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒▐
* ░▐░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄
* ░▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒
* ▀▒▀▐▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒
* 单身狗就这样默默地看着你,一句话也不说。
*/
Java 所有的组成部分都需要名字。
类名、变量名以及方法名都被称为标识符。
关键字 | 含义 |
---|---|
abstract | 表明类或者成员方法具有抽象属性 |
assert | 断言,用来进行程序调试 |
boolean | 基本数据类型之一,声明布尔类型的关键字 |
break | 提前跳出一个块 |
byte | 基本数据类型之一,字节类型 |
case | 用在switch语句之中,表示其中的一个分支 |
catch | 用在异常处理中,用来捕捉异常 |
char | 基本数据类型之一,字符类型 |
class | 声明一个类 |
const | 保留关键字,没有具体含义 |
continue | 回到一个块的开始处 |
default | 默认,例如,用在switch语句中,表明一个默认的分支。Java8 中也作用于声明接口函数的默认实现 |
do | 用在do-while循环结构中 |
double | 基本数据类型之一,双精度浮点数类型 |
else | 用在条件语句中,表明当条件不成立时的分支 |
enum | 枚举 |
extends | 表明一个类型是另一个类型的子类型。对于类,可以是另一个类或者抽象类;对于接口,可以是另一个接口 |
final | 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量 |
finally | 用于处理异常情况,用来声明一个基本肯定会被执行到的语句块 |
float | 基本数据类型之一,单精度浮点数类型 |
for | 一种循环结构的引导词 |
goto | 保留关键字,没有具体含义 |
if | 条件语句的引导词 |
implements | 表明一个类实现了给定的接口 |
import | 表明要访问指定的类或包 |
instanceof | 用来测试一个对象是否是指定类型的实例对象 |
int | 基本数据类型之一,整数类型 |
interface | 接口 |
long | 基本数据类型之一,长整数类型 |
native | 用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的 |
new | 用来创建新实例对象 |
package | 包 |
private | 一种访问控制方式:私用模式 |
protected | 一种访问控制方式:保护模式 |
public | 一种访问控制方式:共用模式 |
return | 从成员方法中返回数据 |
short | 基本数据类型之一,短整数类型 |
static | 表明具有静态属性 |
strictfp | 用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范 |
super | 表明当前对象的父类型的引用或者父类型的构造方法 |
switch | 分支语句结构的引导词 |
synchronized | 表明一段代码需要同步执行 |
this | 指向当前实例对象的引用 |
throw | 抛出一个异常 |
throws | 声明在当前定义的成员方法中所有需要抛出的异常 |
transient | 声明不用序列化的成员域 |
try | 尝试一个可能抛出异常的程序块 |
void | 声明当前成员方法没有返回值 |
volatile | 表明两个或者多个变量必须同步地发生变化 |
while | 用在循环结构中 |
Java属于强类型语言,要求变量的使用要严格符合规定,所有变量都必须先定以后才能使用
必须为每一个变量声明一种类型
安全性高但运行速度较弱类型语言慢
类型 | 存储需求 | 取值范围 |
---|---|---|
int | 4字节 | ±2^31-1 |
short | 2字节 | ±2^15-1 |
long | 8字节 | ±2^63-1 |
byte | 1字节 | ±2^7-1 |
类型 | 存储需求 | 取值范围 |
---|---|---|
float | 4字节 | 有效位数为6~7位 |
double | 8字节 | 有效位数为15位 |
double类型的数值精度是float类型的两倍,因此称为双精度。
定义float类型时,要在数值后添加一个后缀F或f,例如:
float num=3.14f
没有后缀F的浮点数值(如3.14)总是默认为double类型。
所有的浮点数值计算都遵循IEEE 754规范。并存在表示溢出和出错情况的三个特殊的浮点数值:
不能通过如下检测一个特定值是否等于Double.NaN:
if(x == Double.NaN) //is never true
所有“非数值”的值都认为是不相同的。可通过如下方法判断:
if(Double.isNaN(x)) //check whether x is not a number
char类型原本用于表示单个字符。如今,有些Unicode字符可以用一个char值描述,另外一些Unicode字符则需要两个char值。
char类型的字面量值要用单引号括起来。例如:‘A’ 。
码点(code point)是指与一个编码表中的某个字符对应的代码值。在Unicode标准中,码点采用十六进制书写,并加上前缀U+,例如U+0041就是拉丁字母A的码点。Unicode的码点可以分成17个代码平面(code plane)。第一个代码平面称为基本多语言平面(basic multilingual plane),包括码点从U+0000到U+FFFF的“经典”Unicode代码;其余的16个平面的码点为从U+10000到U+10FFFF,包括辅助字符(supplementary character)。
UTF-16 编码采用不同长度的编码表示所有Unicode码点。在基本多语言平面中。每个字符用16位表示,通常称为代码单元(code unit);而辅助字符编码为一对连续的代码单元。
在Java中,char类型描述了UTF-16编码中的一个代码单元。
转义字符 \t(制表) \n(换行) ……
boolean(布尔)类型有两个值:false 和 true,用来判定逻辑条件。整形值和布尔值之间不能进行相互转换。
public class demo1 {
public static void main(String[] args) {
//整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x
int i = 10;
int i2 = 010; //八进制0
int i3 = 0x10; //十六进制0x 0~9、A~F 16
System.out.println(i);
System.out.println(i2);
System.out.println(i3);
//浮点数拓展 BigDecimal 数学工具 类
//float 有限 离散 舍入误差 接近但不等于 -> 容易出错(出现误差)
//避免完全使用浮点数进行比较 -> 用BigDecimal 数学工具 类
float f = 0.1f; // 0.1
double d = 1.0/10; // 0.1
double d2 = 0.1;
System.out.println(f == d); //false
System.out.println(f == d2); //false
float f1 = 121312312334343434343433333333341231223f;
float f2 = f1 + 1;
System.out.println(f1 == f2); //true
//字符拓展
char c1 = 'a';
char c2 = '中';
System.out.println(c1);
System.out.println((int)c1); //强制转换 97
System.out.println(c2);
System.out.println((int)c2); //强制转换 20013
// 所有的字符本质还是数字
// 编码 Unicode 表:97 = a 2字节 0~65536个字符
// 区间 U0000 UFFFF
char c3 = '\u0061';
System.out.println(c3); // a
String sa = new String("hello");
String sb = new String("hello");
System.out.println(sa == sb); //false
String sc = "hello";
String sd = "hello";
System.out.println(sc == sd); //true
}
}
因为Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换。
低 --------------------------------------------------------------- > 高
byte、short、char - > int - > long - > float - > double
在运算过程中,不同类型的数据先转化为同一类型,然后再进行运算。
1.不能对布尔值进行转换
2.不能把对象类型转换为不相干的类型
3.在把高容量转到低容量的时候,强制转换
4.转换时可能存在内存溢出,或精度问题
System.out.println((int)23.7); //23
System.out.println((int)-45.89f); //-45
char c ='a';
int d = c + 1;
System.out.println(d); //98
System.out.println((char)d); //b
int money = 10_0000_0000;
int years = 20;
int total = money * years; //计算时候结果溢出了 -1474836480
System.out.println(total);
long total2 = money * years; //默认是int,在转换之前已经出现问题了 -1474836480
System.out.println(total2);
long total3 = money *((long)years); //先把一个数转化为long 20000000000
System.out.println(total3);
变量就是可以变化的量,常量就是值不变的变量。
Java 变量时程序中最基本的存储单元,其要素包括变量名、变量类型和作用域。
声明一个变量之后,必须用赋值语句对变量进行显式初始化,千万不要使用未初始化的变量的值。
在 Java 中可以将声明放在代码中的任何地方。
变量的声明尽可能地接近变量第一次使用的地方(良好的程序编写风格)。
public class demo3 {
static int all = 0; //类变量
String str = "hello world"; //实例变量
public void method(){
int i = 0 ; //局部变量
}
}
需要加关键词 static 静态的 (修饰符)
和类变量类似,但无 static 关键词
从属于对象
如果不自行初始化,则是这个类型的默认值 0 或 0.0 或 u0000 或 false(布尔) 或 null(引用类型)
demo3 d3 = new demo3();
System.out.println(d3.str);
必须声明和初始化值,作用域在方法内
算数运算符:+、-、*、/、%、++、–
赋值运算符 :=
关系运算符 :>、<、>=、<=、==、!=、instanceof
逻辑运算符:&&、||、!
位运算符: 效率高
- & and
- | or
- ^ xor 相同为0,不同为1
- ~ not
- “>>” 左移
- << 右移
- “>>>” 用 0 填充高位
条件运算符: ?:
跨站赋值运算符:+=、-=、*=、/=
Java 没有内置的字符串类型,而是在标准 Java 类库提供了一个预定义类,叫做String。每个用双引号括起来的字符串都是 String 类。
String 类的 substring 方法可以从一个较大的字符串提取出一个子串。例如:
创建一个字符 “Hel” 组成的字符串
String greeting = "Hello";
String s = greeting.substring(0,3);
Java 语言允许使用 + 号连接(拼接)两个字符串。
public static void main(String[] args) {
// ctrl + d 复制当前行到下一行
int a = 10;
int b = 25;
//注意区别
System.out.println(a+b+"");//35
System.out.println(""+a+b);//1025
System.out.println(a+""+b);//1025
}
String 类没有提供修改字符串中某个字符的方法。
若想将 greeting 的内容修改为 help ,不能直接改变 greeting 。
但可通过保留部分子串,再与希望替换的字符拼接。
greeting = greeting.substring(0,3) + "p";
可以使用 equals 方法检测两个字符串是否相等。对于表达式:
s.equals(t);
如果字符串 s 与字符串 t 相等,则返回 true ;否则,返回 false 。
要想检测两个字符串是否相等,且不考虑大小写,可以使用 equalsIgnoreCase 方法。
"HELLO".equalsIgnoreCase("hello");
为了更好地组织类, Java提供了包机制,用于区别类名和命名空间。
一般利用公司域名倒置作为包名:
为了能够使用某一个包的成员,我们需要在 Java 程序中明确导入该包。使用 “import” 语句即可
import package1[.package2…].(classname|*);
JavaSE: 标准版(桌面程序、控制台开发)
- 基础
JavaME: 嵌入式开发(手机、小家电)
- 差不多死了
JavaEE: 企业级开发(web端,服务器开发)
- 基本就业方向
JDK包含JRE、JVM
JRE包含JVM
cmd中 java -version 检查是否配置JDK
集成开发环境
集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。
IDEA官方网址
psvm - > public static void main(String[] args)
sout - > System.out.println();
后续补充