Java
目录- Java
数据类型
八种基础数据类型:byte、short、int、long、float、double、boolean、char
引用类型:类(String、包装类),数组,接口
类型 | 内存占用 | 取值范围 |
---|---|---|
byte | 1个字节 | -128~127 |
short | 2个字节 | -32768~32767 |
int(整数默认) | 4个字节 | -2的31次方2的31次方-1(-21474836482147483647) |
long | 8个字节 | -2的63次方~2的63次方-1 |
float | 4个字节 | 1.4013E-45~3.4028E+38 |
double(浮点数默认) | 8个字节 | 4.9E-324~1.7977E+308 |
char | 2个字节 | 0-65535 |
boolean | 1个字节 | true,false |
基本数据类型转换
在java中类型转换是一个非常重要的知识点。因为java是一门强类型语言,所以在数据运算中会存在类型转换,首先我们需要知道java中的类型转换一共分为两类:自动类型转换
和强制类型转换
。
public class Test {
public static void main(String[] args) {
byte a = 12; // 12默认是int类型,没超过byte范围,自动转换为byte类型
byte b = 24;
byte c = (byte) (a+b); // 由于a和b都是byte类型,计算时自动a+b时自动转换为int类型,赋值给c利用强制转换
System.out.println(c);
}
}
类型转换:(byte、short、char)——>int———>long——>float—>double。
byte、short、char在计算时都会转换为int类型。boolean类型不能与其他基本数据类型相互转换。
public class Test {
public static void main(String[] args) {
char a = 'a';
int b = 12 + a;
System.out.println(b); // 109
}
}
获取变量数据类型
在Java中,如果想获取变量的类型。
对于简单类型变量,是无法直接获得变量类型的;我们可以通过自定义方法,如下面代码中的getType()获取它的包装类型。
对于包装类型变量,是可以直接获得的,变量名称.getClass().getName()
。
public class Test {
public static void main(String[] args) {
Integer i = 4;
int j = 5;
String s = "hello";
boolean b = true;
System.out.println(getType(b));//java.lang.Boolean
System.out.println(s.getClass().getName());//java.lang.String
System.out.println(i.getClass().getName());//java.lang.Integer
System.out.println(getType(j));//java.lang.Integer
}
public static String getType(Object o) {
return o.getClass().getName();
}
}
long后面加L
在Java中,整数的默认数据类型是int。当我们将一个整数赋值给任何类型变量时,这个整数默认是int型。
如果这个数字小于int的最大值,可以直接给long赋值,因为int的取值范围小于long型,可以自动转换。
如果这个数字大于int的最大值,此时不能自动转换,我们就需要在数字后面加上L来进行强转,否则会报错。
总结:
long是长整型,可以将任意一个整数(默认int)赋值给long类型的变量;
如果这个整数范围处于【int】范围内,它会自动转换为long类型;
如果这个整数范围处于【int,long】范围内,我们需要加上L进行强制转换,超出【long】范围会报错。
public class Test {
public static void main(String[] args) {
long a = 12; // 整数12的默认数据类型是int,赋值时自动转换为long类型
//long b = 2147483648; // 整数2147483648的默认数据类型是int,由于超过了int类型范围,赋值时不能自动转换为float,会报错
long b = 2147483648L; // 因此,需要加上L进行强转
System.out.println(getType(b)); // java.lang.Long
}
public static String getType(Object o) {
return o.getClass().getName();
}
}
float后面加F
在Java中,浮点数的默认数据类型是double,当我们将一个浮点数赋值给任何类型变量时,这个浮点数默认是double型。
如果我们将整数赋值给float,因为float的取值范围大于int,会自动进行转换。
如果我们将浮点数赋值给float,因为float的取值范围小于double,此时需要在后面加上F进行强转换。
总结:
float是单精度浮点型,可以将任意一个整数(默认int)或者小数(默认double)赋值给float类型的变量;
如果这个整数范围处于【int】范围内,它会自动转换为float类型;
如果这个整数范围处于【int,float】范围内,我们需要加上F进行强制转换,超出【float】范围会报错;
如果这个小数范围处于【float】范围内,我们需要加上F进行强制转换,超出【float】范围会报错。
public class Test {
public static void main(String[] args) {
System.out.println(getType(12.3)); //java.lang.Double
float a = 12; // 12是int类型,赋值给float,因为float的取值范围大于int,会自动进行转换。
//float b = 12.5; // 12.5默认是double类型,因为float的取值范围小于double,会报错
float b = 12.5F; // 此时需要在后面加上F进行强转换
}
public static String getType(Object o) {
return o.getClass().getName();
}
}
包装类
Java有八种基本数据类型:byte、short、int、long、float、double、boolean、char
Java为其提供了8种对应的包装类:Byte、Short、Integer、Long、Float、Double、Boolean、Character
使用包装类的原因?
-
Java语言是面向对象的编程语言,而基本数据类型声明的变量并不是对象,为其提供包装类,增强了Java面向对象的性质。
-
如果只有基本数据类型,使用时是很不方便的,比如,在集合类中,无法将int 、double等类型放进去的,因为集合的容器要求元素是Object类型。
-
包装类还为基本类型添加了属性和方法,丰富了基本类型的操作。如当我们想知道int取值范围的最小值,我们需要通过运算,如下面所示,但是有了包装类,我们可以直接使用Integer.MAX_VALUE即可。
System.out.println(Integer.MAX_VALUE); // 2147483647
为什么要保留基本数据类型?
- 因为Java种创建的对象都是存储在堆里的,使用的时候需要通过栈中的引用,所以常用的基本数据类型,不需要使用new在堆上创建,而是直接在栈内存中存储不创建对象,就会比较高效。
包装类的自动拆装箱机制!
进行基本类型数据和包装类对象之间的互转时:
// 创建包装类对象有两种方式:new关键字、valueOf()方法。
Integer num1 = new Integer(1); //基本数据类型转为包装类
Integer num2 = Integer.valueOf(10);//基本数据类型转为包装类
int num3 = num1.intValue(); //包装类型转为基本数据类型
System.out.println(num1); // 1
System.out.println(num2); // 10
System.out.println(num3); // 1
为了方便使用和性能优化,提供了自动拆装箱机制:
//包装类中的自动装箱拆箱机制
Integer num1 = 1; //自动装箱
int num2 = num1; //自动拆箱
System.out.println(num1); // 1
System.out.println(num2); // 1
new出来的对象是在堆中开辟了新地址,所以地址不相同,而根据源码分析valueOf创建的对象在-128~127时是有一个cache数组存储的,也就是我们常说的128陷阱。
Integer a1 = new Integer(127);
Integer a2 = new Integer(127);
System.out.println(a1==a2); // false
Integer b1 = Integer.valueOf(127);
Integer b2 = Integer.valueOf(127);
System.out.println(b1==b2); // true
变量类型
Java语言支持的变量类型有:
静态变量
又称类变量,独立于方法之外的变量,用 static 修饰,有默认值
。静态变量可以由静态方法访问或赋值,也可以创建对象访问。
-
无论一个类创建了多少个对象,类只拥有静态变量的一份拷贝。
-
静态变量在第一次被访问时创建,在程序结束时销毁。
-
静态变量可以通过:ClassName.VariableName的方式访问。
-
final 静态变量初始化后不可改变。
-
类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母。如果静态变量不是 public 和 final 类型,其命名方式与实例变量以及局部变量的命名方式一致。
public class Test { static String name; // 静态变量可以由普通方法和静态方法访问,也可以创建对象访问。 public static void main(String[] args) { System.out.println(name); // null System.out.println(Test.name); //null Test t = new Test(); t.read(); //zhangsan } public void read(){ name ="zhangsan"; System.out.println(name); } }
成员变量
又称实例变量,独立于方法之外的变量,不过没有 static 修饰,有默认值
。
-
当一个对象被实例化之后,每个实例变量的值就跟着确定;
-
实例变量在对象创建的时候创建,在对象被销毁的时候销毁;
-
实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息,即需要创建对象才可以访问。
public class Test { String name; // 成员变量,需要创建对象访问,也可以赋值。 public static void main(String[] args) { Test t = new Test(); t.name="aa"; System.out.println(t.name); } }
局部变量
-
类的方法中的变量。局部变量
没有默认值
,所以局部变量被声明后,必须经过初始化,才可以使用。-
局部变量声明在方法、构造方法或者语句块中;
-
局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
-
访问修饰符不能用于局部变量;
-
局部变量只在声明它的方法、构造方法或者语句块中可见;
public class Test { public static void main(String[] args) { String name; name = "zhangsan"; System.out.println(name); } }
-
变量默认初始值
静态变量和成员变量都有默认值;而局部变量没有默认值,必须经过初始化,才可以使用。
数据类型 | 默认值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
char | 'u0000' |
String (or any object) | null |
boolean | false |
引用类型 | null |
public class cccc {
static boolean bool;
static byte by;
static char ch;
static double d;
static float f;
static int i;
static long l;
static short sh;
static String str;
// 注意,静态方法只能访问静态变量
public static void main(String[] args) {
System.out.println("Bool :" + bool); //Bool :false
System.out.println("Byte :" + by); //Byte :0
System.out.println("Character:" + ch); //Character:
System.out.println("Double :" + d); //Double :0.0
System.out.println("Float :" + f); //Float :0.0
System.out.println("Integer :" + i); //Integer :0
System.out.println("Long :" + l); //Long :0
System.out.println("Short :" + sh); //Short :0
System.out.println("String :" + str); //String :null
}
}
运算符
算数运算符
运算符 | 描述 |
---|---|
+ |
加法运算,字符串连接运算 |
- |
减法运算 |
* |
乘法运算 |
/ |
除法运算 |
% |
取模运算,两个数字相除取余数 |
++ 、-- |
自增自减运算 |
赋值运算符
运算符 | 描述 |
---|---|
= |
等于号 |
+= |
加等于 |
-= |
减等于 |
*= |
乘等于 |
/= |
除等于 |
%= |
取模等 |
比较运算符
运算符 | 描述 |
---|---|
== |
比较符号两边数据是否相等,相等结果是true。 |
< |
比较符号左边的数据是否小于右边的数据,如果小于结果是true。 |
> |
比较符号左边的数据是否大于右边的数据,如果大于结果是true。 |
<= |
比较符号左边的数据是否小于或者等于右边的数据,如果小于结果是true。 |
>= |
比较符号左边的数据是否大于或者等于右边的数据,如果小于结果是true。 |
!= |
不等于符号 ,如果符号两边的数据不相等,结果是true。 |
逻辑运算符
运算符 | 描述 |
---|---|
&& |
与运算 |
` | |
! |
非运算 |
与运算特点:符号左边是false,右边不再运算;符号左边是true,右边继续运算。
或运算特点:符号左边是true,右边不再运算;符号左边是false,右边继续运算。
三元运算符
布尔类型表达式?a:b
布尔类型表达式结果是true,三元运算符整体结果为a
布尔类型表达式结果是false,三元运算符整体结果为b
位运算符
符号 | 描述 | 运算规则 |
---|---|---|
& |
与 | 两个位都为1时,结果才为1 |
` | ` | 或 |
^ |
异或 | 两个位相同为0,相异为1 |
~ |
取反 | 0变1,1变0 |
<< |
左移 | 各二进位全部左移若干位,高位丢弃,低位补0 |
>> |
右移 | 各二进位全部右移若干位,对无符号数,高位补0。各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) |
原码、反码、补码
首先,我们得清楚机器数、真值、原码、反码、补码的概念。
机器数:一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号,正数为0,负数为1。
原码、反码、补码都是机器数。例如:5 的机器数是:00000101 ; -5的机器数是:10000101 (以8位二进制为例)
真值:真值指的是带符号位的机器数对应的真实数值。真值一般用十进制表示,也可以用二进制表示,很少用其他进制表示真值。
例如:10000101 的真值= -0000101 = -5 ; 00000101 的真值= +0000101 =+5
原码、反码、补码:对于一个数, 计算机要使用一定的编码方式进行存储;原码, 反码, 补码是机器存储一个具体数字的编码方式。
原码:表示形式就是第一位是符号位加上真值的绝对值。
原码是最容易被大脑理解,计算的表示形式。
反码:在原码的基础上,如果是正数,就和原码一样,如果是负数,首位符号不变,其余数值取反。
反码不容易被大脑理解,通常被转换成原码后计算。
补码:在原码的基础上,如果是正数,就和原码一样,如果是负数,首位符号不变,其余数值取反,在它的基础上 +1。
对于负数, 补码表示方式也是人脑无法直观看出其数值的,通常也需要转换成原码再计算其数值。
流程控制
数组
数组
数组是一个容器,同一种数据类型的集合。数组可以存储多种元素类型,如byte、short、int、long、float、double、char、boolean、引用类型
。
每个数组都有一个属性length指明它的长度,数组一旦初始化,其长度是不可变的。数组初始化时一定需要指定长度。
数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[长度];
创建一个数组,并指定长度,
int[] arr = new int[3]; // 长度为3,数组下标则为:0,1,2
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
创建一个数组并赋值。
int[] arr = new int[]{1,2,3,4,5};
数据类型[] 数组名 = {元素1,元素2,元素3...};
创建一个数组并赋值。
int[] arr = {1,2,3,4,5};
下面举例存储一个引用类型:
public class test {
public static void main(String[] args) {
Person p1 = new Person("张三", 12);
Person p2 = new Person("李四", 22);
Person[] persons = new Person[2];
persons[0] = p1;
persons[1] = p2;
for (int i = 0; i <persons.length ; i++) {
System.out.println(persons[i]);
}
//输出:
//Person{name='张三', age=12}
//Person{name='李四', age=22}
}
}
class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
默认初始值
声明数组后,若没有对数组赋值,数组会有一个初始默认值。
数组元素类型 | 元素默认初始值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
char | 0或'\u0000'(表现为空) |
boolean | false |
引用类型 | null |
遍历
注意,数组不能添加元素,只能利用下标赋值。
数组的遍历方式有3种,Arrays.toString方法、foreach循环(增强for)、for循环。当然也可以将数组转换成集合再输出。
import java.util.Arrays;
public class test {
public static void main(String[] args) {
int[] ints = new int[]{2,11,7,15};
for (int i:ints) {
System.out.println(i);
}
for (int i = 0; i < ints.length; i++) {
System.out.println(ints[i]);
}
System.out.println(Arrays.toString(ints)); //[2, 11, 7, 15]
}
}
数组算法
- 数组元素的赋值(杨辉三角、回形数等)
- 求数值型数组中元素的最大值、最小值、平均数、总和等
- 数组的复制、反转、查找(线性查找、二分法查找)
- 数组元素的排序算法
类与对象
一个类中,可以有成员变量、静态变量、构造函数、静态代码块、成员方法、静态方法
。其中,成员方法和静态方法都可以重载。
public class Test {
public static void main(String[] args) {
Per per = new Per();
System.out.println(Per.num);
System.out.println(per.num);
Per per1 = new Per();
per1.printPer();
}
}
class Per{
private String name; // 成员变量
private Integer age; // 成员变量
public static Integer num = 0; // 静态变量:静态方法访问,类名访问,对象访问。
public Per() { // 无参构造方法
}
public Per(String name, Integer age) { // 有参构造方法
this.name = name;
this.age = age;
}
public void priPer(){ // 成员方法
System.out.println(this.name + this.age);
}
public static void printPer(){ // 静态方法:类名访问,对象访问
System.out.println(num);
}
}
成员变量
封装private、this
静态变量
任何对象可以访问赋值;可以不创建对象,使用类名访问。
构造方法
初始化成员变量。
静态代码块
static{
//...
}
随着类的加载执行一次,优于构造方法和main方法
成员方法
一般情况下,定义一个方法包含以下语法:
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
静态方法
建议使用类名调用,不建议创建对象使用
可直接访问静态变量和静态方法
可被成员方法访问
静态方法不能含有this
重载
无论是成员方法和静态方法都可以重载。
方法重载:指在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可,与修饰符和返回值类型无关。
参数列表:个数不同,数据类型不同,顺序不同。
重载方法调用:JVM通过方法的参数列表,调用不同的方法。
继承
java中的类只有单继承,即一个类只有一个父类。
-
子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有。
-
子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
-
子类可以用自己的方式实现父类的方法。
成员变量
不重名不影响;如果重名,使用this、super。
成员方法
不重名不影响;如果重名,重写
。
构造方法
子类有super()
抽象类与接口
抽象类:
-
没有方法体的方法叫抽象方法;包含抽象方法的类叫抽象类;
-
继承抽象类的子类必须重写所有抽象方法,否则该子类也必须是抽象类;
-
抽象类中可以有构造方法,供子类调用父类方法,子类默认有super构造;
-
抽象类中不一定含抽象方法,但有抽象方法的类一定是抽象类;
接口:
接口中有:抽象方法abstract、默认方法default、静态方法static、私有方法private
- 只有默认方法可以调用私有静态方法
- 默认和静态方法可以调用
- 非抽象子类实现接口必须重写所有抽象方法
- 接口中无法定义成员变量,可以定义public static final常量接口中没有构造方法和静态代码块
区别:
- 都是提取通用特性区别
- 抽象类是单继承
- 接口可以多继承多实现
接口和抽象类的区别:
接口的设计目的,是对类的行为进行约束;抽象类的设计目的,是代码复用。
-
抽象类可以存在普通成员方法,而接口中只能存在public abstract方法。
-
抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的。
-
抽象类只能继承一个,接口可以实现多个。
继承和实现的关系:
-
接口与接口:多继承;即一个接口可同时继承多个父接口;可不用重写父接口抽象方法。
-
接口与类:多实现;即一个类可同时实现多个父接口;必须重写父接口与超接口的抽象方法
-
接口与抽象类:多实现;即一个抽象类可同时实现多个父接口;可不用重写父接口与超接口的抽象方法
-
抽象类与抽象类:单继承;可不用重写父类和抽象方法
-
类与抽象类:单继承;必须重写父类超类的抽象方法
多态
多态,顾名思义,表示一个对象具有多种的状态,具体表现为父类的引用指向子类的实例。
当使用多态方式调用方法时,首先检查父类中是否有该方法。如果没有,则编译错误;如果有,执行的是子类重写后方法。如果子类没有覆盖父类的方法,执行的是父类的方法。
可变参数
- 调用可变参数的方法时,传入实参的个数可以是0~n。(n = 0,1,2......)。
- 传入的实参也可以直接是一个数组。
- 可变参数的本质,其实就是一个数组,因此你也可以把它当数组来用。
- 当形参中既含有可变参数,也含有普通的参数,必须确保可变参数在形参列表的最后。
- 每个形参列表都只能有一个可变参数。
public class Test {
public static void main(String[] args) {
int add = add(1, 2, 3, 4);
System.out.println(add);
int[] arr = new int[]{1,2,3,4};
int add1 = add(arr);
System.out.println(add1);
}
public static int add(int...num){
int sum = 0;
for (int i = 0; i < num.length; i++) {
sum+=num[i];
}
return sum;
}
}
泛型通配符
常见关键字
final
不可改变。可以用于修饰类、方法和变量。
-
类:被修饰的类,不能被继承。
-
方法:被修饰的方法,不能被重写。
-
局部变量——基本类型:被final修饰后,只能赋值一次,不能再更改。
-
局部变量——引用类型:被final修饰后,只能指向一个对象,地址不能再更改。
-
成员变量
被final修饰的常量名称,一般都有书写规范,所有字母都大写。
static
用来修饰的成员变量和成员方法
,被修饰的成员是属于类的,而不是单单是属于某个对象的。
-
类变量:使用 static关键字修饰的成员变量。
-
类方法:使用 static关键字修饰的成员方法,习惯称为静态方法。
-
静态方法可以直接访问类变量和静态方法。
-
静态方法不能直接访问普通成员变量或成员方法。反之,成员方法可以直接访问类变量或静态方法。
-
静态方法中,不能使用this关键字。
this
super
volatile
权限修饰符
public | protected | default | private | |
---|---|---|---|---|
同一类中 | √ | √ | √ | √ |
同一包中(子类与无关类) | √ | √ | √ | |
不同包子类 | √ | √ | ||
不同包无关类 | √ |
Scanner
java.util.Scanner
构造方法
public Scanner(InputStream source):构造 Scanner,它生成的值是从指定的输入流扫描的。
成员方法
public int nextInt():将输入信息的下一个标记扫描为一个 int 值。
获取用键盘输入常用的两种方法:
//通过Scanner
Scanner input = new Scanner(System.in);
String s = input.nextLine();
input.close();
//通过BufferedReader
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String s = input.readLine();
Random
java.util.Random
构造方法
public Random() :创建随机数生成器。
成员方法
public int nextInt(int n) :返回一个伪随机数,范围是[0 , n)
Arrays
java.util.Arrays
静态方法
public static String toString(int[] a) :返回指定数组内容的字符串表示形式。
public static void sort(int[] a) :对指定的 int 型数组按数字升序进行排序。
Math
java.lang.Math
静态方法
public static double abs(double a) :返回 double 值的绝对值。
public static double ceil(double a) :返回大于等于参数的最小的整数。
public static double floor(double a) :返回小于等于参数最大的整数。
public static long round(double a) :返回最接近参数的 long。(相当于四舍五入方法)
String
java.lang.String
构造方法
public String() :创建一个空串。
public String(char[] value) :通过字符数组创建字符串。
public String(byte[] bytes) :通过使用平台的默认字符集解码字节数组来构造字符串。
判断方法
public boolean equals (Object anObject) :将此字符串与指定对象进行比较。
public boolean equalsIgnoreCase (String anotherString) :将此字符串与指定对象进行比较,忽略大小写。
获取方法
public int length () :返回字符串的长度。
public String concat (String str) :将指定的字符串连接到该字符串的末尾。
public char charAt (int index) :返回指定索引处的字符值。
public int indexOf (String str) :返回指定子字符串第一次出现在该字符串内的索引。
public String substring (int beginIndex) :返回一个子字符串,从beginIndex开始截取字符串到字符串结尾。
public String substring (int beginIndex, int endIndex) :从[beginIndex,endIndex)截取字符串。
转换方法
public char[] toCharArray () :将此字符串转换为字符数组。
public byte[] getBytes () :使用平台的默认字符集将该字符串编码转换为字节数组。
public String replace (CharSequence target, CharSequence replacement) :将与target匹配的字符串使用replacement字符串替换。
分割方法
public String[] split(String regex) :将此字符串按照给定的regex(规则)拆分为字符串数组。
标签:java,变量,int,System,static,public,String From: https://www.cnblogs.com/cg9496/p/17273777.html