位运算符
"<<"有符号左移运算,二进制位向左移动,左边舍弃,右边补0
运算规律:向左移动几位,就乘以2的几次幂,如:12<<2 = 12*2² = 48
">>"有符号右移运算,二进制位向右移动,右边舍弃,使用符号位进行补位
运算规律:向右移动几位,就除以2的几次幂,如3>>1 = 3/2 =1
">>>"无符号右移运算符,无论符号位是0还是1,都补0
"^"异或运算符的特点:
一个数,被另一个数异或两次,结果为该数本身
示例:数据交换(不允许使用第三方变量)
/** ^ 异或运算符特点:一个数被另一个数异或两次,结果为该数本身
* 实现数据交换,不允许使用第三方变量*/
public class Test1 {
public static void main(String[] args) {
int a = 10,b = 20;
a = a^b;
//即b = a^b^b;亦即b = a;
b = a^b;
//即a = a^b^a;亦即a = b;
a = a^b;
}
}
案例:数组反转
/**
* 使用异或运算符实现数组元素反转
*/
public class Test2 {
public static void main(String[] args) {
int[] arr ={13,45,23,54,64,12};
int j = arr.length-1;
for (int i = 0; i < arr.length/2; i++,j--) {
arr[i] = arr[i]^arr[j];
arr[j] = arr[i]^arr[j];
arr[i] = arr[i]^arr[j];
}
for (int x : arr) {
System.out.println(x);
}
}
}
二维数组
/**
* 二维数组动态初始化
*/
public class Demo04 {
public static void main(String[] args) {
int[][] arr = new int[3][3];
/*
* arr地址:[[I@1b6d3586
* @:分隔符
* 1b6d3586:arr的十六进制内存地址
* I:数据类型
* [[:数据维数*/
System.out.println(arr);
//一维数组地址:[I@4554617c
System.out.println(arr[0]);
//二维数组元素初始化赋值
arr[0][0] = 12;
arr[1][1] = 4;
arr[2][2] = 55;
for (int[] x : arr) {
for (int i : x) {
System.out.println(i);
}
}
}
}
package com.shifan.base.arrays;
/**
* 提前定义一维数组赋值给二维数组元素,
*/
public class Demo05 {
public static void main(String[] args) {
int[][] arr1 = new int[3][3];
int[] arr2 = {1,3,3};
int[] arr3 = {3,5,2,5};
arr1[0] = arr2;
//arr1[1][3] = 10;直接对arr1[1][3]赋值会报数组越界错误
/*
提前定义的数组arr3长度超过了二维数组长度
赋值给arr1[1]之后arr1[1]指向了arr3,arr1[1]的长度变为4
*/
arr1[1] = arr3;
//这里对超过二维数组长度的元素赋值不会报错
arr1[1][3] = 10;
//输出1,3,3
for (int i : arr1[0]) {
System.out.println(i);
}
//输出3,5,2,10
for (int i : arr1[1]) {
System.out.println(i);
}
}
}
面向对象
public class Test{
public static void main(String[] args){
//创建一个Student对象
Student stu = new Student();
/*
* 输出:com.shifan.oop.demo01.Student@1b6d3586
* @:分隔符
* com.shifan.oop.demo01.Student:全类名
* 1b6d3586:十六进制内存地址*/
System.out.println(stu);
}
}
class Student{
String name;
}
public class Test{
public static void main(String[] args){
Student stu = new Student();
//输出null
System.out.println(stu.name);
stu.name = "shifan";
//输出shifan
System.out.println(stu.name);
}
}
class Student{
String name;
}
上面代码内存图如下
同一个类创建的两个对象,在创建第二个对象的时候,不需要再次加载该类的字节码文件进方法区
当堆内存中,对象或数组产生的地址,通过任何方式都不能被找到后,就会被判定为内存中的"垃圾",垃圾会被java垃圾回收器在空闲的时候自动清理
成员变量有默认初始化值,局部变量没有,必须先定义赋值再使用
private关键字
被private修饰的成员只有在本类中才能被访问
this关键字
this:代表所在类的对象引用
记住:方法被哪个对象调用,this就代表哪个对象
this关键字可以调用本类的成员,解决了成员变量与局部变量重名的问题,成员变量与局部变量重名时,java采用的是就近原则
封装
定义:隐藏实现细节,仅对外暴露公共的访问方式
常见体现:1.私有成员变量,提供get和set方法
2.将代码抽取到方法中,是对代码的封装
3.将属性抽取到类当中,是对数据的封装
package com.shifan.oop.test;
/**
* 定义一个标准类
*/
public class TestStudent {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setAge(10);
stu1.setName("shifan");
stu1.show();
Student tom = new Student("tom", 34);
tom.show();
}
}
package com.shifan.oop.test;
/**
* JavaBean类:封装数据
*/
public class Student {
private String name;
private int age;
public void show(){
System.out.println(name+"..."+age);
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}