由于有少许C++的基础,所以学起Java来相对容易些,不会像刚学C++时一头雾水。
我是通过两种方式进行学习Java的,第一是在B站看的网课
Java零基础入门全套教程_高淇Java300集_适合0基础小白的Java入门教程_哔哩哔哩_bilibili;
还有就是在
JAVA 基础 |Java全栈工程师 | 以实例驱动学习 | how2j.cn中进行学习;
Java和C++在前期有很大一部分是相同的。所以在这里我只说明一些新的东西和我不熟悉的东西;
相比与C++,Java是一种更纯粹的面向对象程序设计语言。在Java中,一切都被视为对象。
Java引入了垃圾回收机制,令C++程序员最头疼的内存管理问题迎刃而解。Java程序员可以将更多的精力放到业务逻辑上而不是内存管理工作上,大大的提高了开发效率。
一.变量数据类型与运算符
此部分与c++绝大多数都是一致的;
使用Scanner,前面加import java.util.Scanner;
import java.util.Scanner;
Scanner s = new Scanner(System.in);
int a = s.nextInt(); //读取整数
float a = s.nextFloat(); //读取浮点数
String a = s.nextLine(); //读取字符串
System.out.println("整数:"+a);
二.控制语句
此部分与c++依旧绝大多数都是一致的;
选择法排序:
for (int j = 0; j < a.length-1; j++) {
for (int i = j+1; i < a.length; i++) {
if(a[i]<a[j]){
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
冒泡排序:
for (int j = 0; j < a.length-1; j++) {
for (int i = j+1; i < a.length; i++) {
if(a[i]<a[j]){
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
二分法查找
int[]arr ={}
Arrays.sort(arr);
int value=10;//要查找的值
public static int Search(int[] arr,int value)
int low=0; int high=arr.length-1;
while(low<=high){
int mid =(low+high)/2;
if(value==arr[mid]){
return mid;
}
if(value>arr[mid]){
low=mid+1;
}
if(value<arr[mid]){
high=mid-1;
}
}
带标签的break和continue :控制嵌套循环跳转
outer: for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
continue outer;
}
public class Test{
public static void main (string []args){
label;//使用前需要先定义标记
for(int i=1;i<10;i++)
{System.out.println(i);
break label;}}
}
三,数组
int[] s = null; // 声明数组;
s = new int[10]; // 给数组分配空间;
静态初始化
int[] a = { 1, 2, 3 };// 静态初始化基本类型数组;
Man[] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组;
动态初始化
int[] a1 = new int[2];//动态初始化数组,先分配空间;
a1[0]=1;//给数组元素赋值;
a1[1]=2;//给数组元素赋值;
数组的默认初始化
int a2[] = new int[2]; // 默认值:0,0
boolean[] b = new boolean[2]; // 默认值:false,false
String[] s = new String[2]; // 默认值:null, null
增强for循环: //只能取值,不能修改
String[] ss = { "aaa", "bbb", "ccc", "ddd" };
for (String each : ss) {
System.out.println(each);
}
数组拷贝:
System.arraycopy(src,srcPos,dest,destPos,length);
//src是一个数组名,srcPos是从src哪开始拷,dest是一个数组名,destPods是拷到dest哪里开始.length是要拷贝的长度。
String[] s1={"aa","bb","cc","dd","ee"};
String[] s2=new String[10];
System.arraycopy(s1,2,s2,6,3)
// null null null null null null cc dd ee null
删除数组中某个元素,还是拷贝
移动数组中元素
//移动数组中元素
pubic staticString[]removeElment(String[] s,int index){
System.arraycopy(s,index+1,s,index,s1.length-index-1);
s1[s.length-1]=null;
...
return s;
}
数组扩容
//数组扩容,先定义一个更大的数组,再将原数组原封不动拷贝到新数组中
public static String[] extendRange(String[] s1){ //void 也可,不用传String[] s1;
String[] s1={"aa","bb","cc","dd","ee"};
String[] s2=new String[s1.length+10];
System.arraycopy(s1,0,s2,0,s1.length);
for(String temp:s2){
System.out.println(temp);
return s2;
}
}
二维数组
声明及初始化:
int[][ ] a=new int[3][];
a[0]=new int[]{20,30};
a[2]=new int[]{50,60};
int b[][]={
{20,30,10},
{10,80},
{60,40}};
}
二维数组的动态初始化 :
Object[] emp1={1001,"g";2001};
Object[] emp2={1002,"s";2002};
Object[] emp3={1003,"t";2003};
Object[][] tableDate =new object[3][];
tableDate[0]=emp1;
tableDate[1]=emp2;
tableDate[2]=emp3;
获取数组的长度:
//获取的二维数组第一维数组的长度。
System.out.println(a.length);
//获取第二维第一个数组长度。
System.out.println(a[0].length);
四.Java面对对象
栈的特点如下:
1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
3. 栈属于线程私有,不能实现线程间的共享!
4. 栈的存储特性是“先进后出,后进先出”
5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!
堆的特点如下:
1. 堆用于存储创建好的对象和数组(数组也是对象)
2. JVM只有一个堆,被所有线程共享
3. 堆是一个不连续的内存空间,分配灵活,速度慢!
方法区(又叫静态区)特点如下:
1. JVM只有一个方法区,被所有线程共享!
2. 方法区实际也是堆,只是用于存储类、常量相关的信息!
3. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)
this
this的本质就是“创建好的对象的地址”! 由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表“当前对象” 。
C++中是this->name;
而在Java中为this.name=name;
super
可以用来修饰属性,方法,构造器
f(){}
super.f();
构造方法的第一句总是super()
1、当子类与父类有同名的属性时,可以通过super属性的方式调用父类中生命的属性。
2、当子类重写父类的方法后,在子类中若想调用父类中被重写的方法时,需用super.的方法
3、super修饰构造器,通过在子类中使用super列表参数的形式调用父类中制定的构造器
a、在构造器内部,super(参数列表)必须声明在首行
b、在构造器内部,this(参数列表)或super(参数列表)只能出现一个
c、当构造器中不显示的调用this(参数列表)或super(参数列表)默认调用父类中的空参 构造器
public childclass extends fatherclass{
public childclass(){
super();//默认的
System.out.println();
}
} //子->父->object
注意:在类中,用static声明的成员变量为静态成员变量,也称为类变量static成员变量只有一份。被该类的所有对象共享!!在static方法中不可直接访问非static的成员。
static修饰的成员变量和方法,从属于类。普通变量和方法从属于对象的。
没有static需要有对象才能调用。加static可直接调用,不用再new。
为什么this super不能用在static方法中
this : 代表当前自身类的对象,可以调用当前类的构造方法,成员变量和成员方法等
super : 代表对父类的引用 , 可以调用父类构造方法,成员变量和方法
因为static方法和类的实例(对象)是两码事,它只在类装载的时候初始化,被称作类级变量(属于类);而类的实例是在程序运行的时候(即Java命令的时候)初始化,被称作对象级变量(属于对象);
this表示这个类的当前实例,super表示父类的当前实例,static是属于类的,this是类的一个对象,
this指针是指向类的对象,在实例化对象时jvm会在堆区分配内存给一个具体的对象,this指针指向这个对象。而类中的static域始终是在静态区分配内存,this指向堆区,所以不能调用。
因此this super不能用在static方法中
Package
为了便于管理,将处理同一方面的问题的类放在同一个目录下,引入了包
包定义:
package 包名; //声明
package(包) 域名倒着写 cn.gst.oo
cn.gst.oo.User user=new cn.gst.oo.User();(有点繁琐) //使用其他包的类
//使用其他包的类,用import. import cn.gst.oo.User;
使用 import 导入单个类 import 包名+类名;
直接导入指定类 import example.Test;
使用 import 语句导入指定包下全部类 import example.*;
单例模式 : 只有一个实例存在,给别的类用
什么是单例模式?
1. 构造方法私有化
2. 静态属性指向实例
3. public static的 getInstance方法,返回第二步的静态属性
饿汉式单例模式:未使用就已经实例化。
//GiantDragon 提供了一个public static的getInstance方法,外部调用者通过该方法获取12行定义的对象,而且每一次都是获取同一个对象。 从而达到单例的目的。
private test(){ //通过私有化其构造方法,使得外部无法通过new 得到新的实例。
}
private static test instance = new test();//准备一个类属性,指向一个实例化对象。 因为是类属性,所以只有一个
public static txst getInstance(){ //public static 方法,提供给调用者获取定义的对象
return instance;
}
懒汉式单例模式:使用时才实例化。
private test(){ //私有化构造方法使得该类无法在外部通过new 进行实例化
}
private static test instance=null; //准备一个类属性,用于指向一个实例化对象,但是暂时指向null
public static test getInstance(){ //public static 方法,返回实例对象
if(null==instance){ //第一次访问的时候,发现instance没有指向任何对象,这时实例化一个对象
instance = new test(); //返回 instance指向的对象
}
什么时候使用饿汉式,什么时候使用懒汉式:
饿汉式是立即加载的方式,无论是否会用到这个对象,都会加载。
懒汉式,是延迟加载的方式,只有使用的时候才会加载。
使用懒汉式,在启动的时候,会感觉到比饿汉式略快,因为并没有做对象的实例化。 但是在第一次调用的时候,会进行实例化操作,感觉上就略慢。
有比较充分的启动和初始化时间,就使用饿汉式,否则就使用懒汉式
类型转换:
子类转父类(向上转型),一定可以的
父类转子类(向下转型),所以要进行强转
instanceof 类名 判断一个引用所指向的对象,是否是父类,或者子类
(二元运算符,左边是对象,右边是类,当是右边类或子类创建的对象时,返回true,否则返回false)
Object obj = new String(" ");
if(obj instanceof String){ //判断所指向的对象
String str = (String)obj;
System.out.println(str.charAt(0));
}else if(obj instanceof StringBuffer){
StringBuffer str = (StringBuffer) obj;
System.out.println(str.charAt(0));
}
向上转型:父亲引用指向子类对象或者 子类转为父类(小转大,不需要强转)
向下转型:子类引用指向父类对象 或者父类转子类(大转小,需强转)
C++在类中默认private,Java默认为default
修饰符 | 同一个类 | 同一个包 | 子类 | 所有类 |
private | √ | |||
default | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
final
1.修饰变量:被他修饰的变量不可改变,一旦赋了初始值,就不能被重新赋值
2.修饰方法:该方法不可被子类重写,但可以被重载
3.修饰类:修饰的类不能被继承。例如String,Math。
4.修饰引用:h引用被修饰成final,表示该引用只有1次指向对象的机会,依然通过h引用修改对象的属性值hp,因为hp并没有final修饰
final Hero h;
h =new Hero();
h =new Hero();//错误
h.hp = 5;
5.常量指的是可以公开,直接访问,不会变化的值
public static final int itemTotalNumber = 6;