hello world的组成部分:
示例(记事本写):
class Demo
{
public static void main(String[] args)
{
System.out.println("Hello java");
}
}
使用cmd命令行进行编译javac Demo.java,注意大小写!
然后文件夹将生成.class文件,此时使用java Demo将运行代码。显示以下结果:
注释:
与C++注释方法一致,注意多行注释之间不能嵌套!(/* class static... */ //注释)
/*
需求:定义一个hello world小程序。
思路:
1.
2.
步骤:
1.通过class关键字定义一个类。将代码写进类中。
2.为了保证独立运行。在类中定义一个主函数,格式public static void main(String[] args)
3.保存成一个扩展名为java的文件。
4.在dos控制台中通过javac工具对java文件进行编译。
5.再通过java命令对生成的class文件进行执行。
*/
class Demo //定义一个类
{
//主函数
public static void main(String[] args)
{
System.out.println("hello java");//输出语句
}
}
标识符:
数字不可以开头
关键字不可以作为标识符
严格区分大小写
常量:
整数:
二进制01
十进制0-9满十进一
八进制0-7满8进1,用0开头表示。
十六进制0-9,A-F,满16进1,用0x开头表示。
小数:
12.34
布尔型常量:
false、true.
字符常量:
‘a’
字符串常量:
"123"
null常量:
null
变量:
就是将不确定的数据进行存储。也就是需要在内存中开辟一个空间。
开辟内存空间:名称(变量名)、空间的类型(数据类型)。
基本数据类型:byte、short、int、long、float、double、char、boolean
引用数据类型:类class、接口interface、数组[]
整数默认int、小数默认double。
类型转换:
注意:byte b = 2;
b = b+3;
此时3为int型,但b为byte型,b最终报错,不能存放int型变量,需要改为b = (byte)(b+2);//强制转换
运算符:
注意a++和++a的区别。
注意字符串相加都是字符串拼接,如果是加数字也是变成字符串。
转义字符:
\n:换行
\b:退格,相当于backspace键
\r:按下回车键
\t:制表符,相当于tab键
windows系统,回车符是由\r\n表示。
赋值:
short s = 4;
s = s+5;//编译失败
s += 5;//编译成功
原因:因为s提升为int类型,运算之后的结果是int类型,但无法赋值给short类型。
因为+=运算符在给s赋值时,自动完成了强转操作。
逻辑运算符:
&与&&的区别:
&无论左边是否为true,右边都运算
&&当左边为false,右边不运算
|两边都运算
||当左边为true,右边不运算
位运算符:
3<<2 = 12; 3<<1 = 6; 3<<3 = 24; ( 3*2^X )左移等于乘以2的几次幂
6>>2 = 1 ; 6>>1 = 3; 右移就是除以2的移动的位数次幂
>>:最高位补0或1由原有数据的最高位值决定
>>>:最高位由0补
注意:一个数异或同一个数两次,结果还是那个数。
不用第三方变量进行交换:
int n = 3, m = 8;
m = n+m;
n = m-n;
m = m-n;//如果n和m值非常大,容易超出范围
////////////////////////////////////
技巧:
n = n^m;
m = n^m;
n = n^m;
////////////////////////////////
注意实际开发用第三方变量较多。
程序流程控制:
判断结构:if ... else ...
if ... else if ... else ...
选择结构:switch{case 取值1:break; case 取值2:break; default:break; }
循环结构:while,do while,for
其他流程控制语句:break,continue
函数:
函数的格式:
修饰符 返回值类型 函数名(参数类型 形式参数1, 参数类型 形式参数2, ...)
{
执行语句;
return 返回值;
}
建议类名和文件名相同。
如何定义一个函数?
1.先明确功能的运算结果
2.再明确在定义该功能的过程中是否需要未知的内容参与运算
例如:需求:定义一个功能,完成3+4的运算,并将结果返回给调用者。
1.明确功能的结果:是一个整数的和。
2.在实现该功能的过程中是否有未知内容参与运算(此功能中无未知内容)
其实这是明确函数的返回值和参数列表(参数个数和类型)
public static int getSum()
{
return 3+4;
}
函数重载:
重载和参数列表有关系,与返回值类型无关,同时参数类型顺序也需要判断。
数组:
同一种类型数据的集合
int[] x = new int[3];
int[] arr = new int[]{3,1,4,2,5};
int[] arr = {3,1,4,6,7};
数组操作:
获取数组中的元素,通常会用到遍历。
选择排序:
内循环结束一次,最值出现头角标位置上。
public static void selectSort(int[] arr)
{
for(int x=0; x<arr.length-1; x++)
{
for(int y=x+1; y<arr.length; y++)
{
if(arr[x]>arr[y])
{
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
}
冒泡排序:
相邻的两个元素进行比较,如果符合条件换位。
public static void bubbleSort(int[] arr)
{
for(int x = 0; x<arr.length-1; x++)
{
for(int y = 0; y<arr.length-x-1; y++)
{
if(arr[y]>arr[y+1])
{
int temp = arr[y];
arr[y] = arr[y+1];
arr[y+1] = temp;
}
}
}
}
希尔排序最快。
二维数组:
int[][] arr = new int[3][4];//定义了名称为arr的二维数组,二维数组中有3个一维数组,每一个一维数组中有四个元素
int[][] arr = {{1,2,3,7},{2,4,5},{4,5,6,8}};
内存结构:
栈:调用函数,开辟内存;数据使用完毕,会自动释放。局部变量在栈中。
堆:new出来的对象在堆中。对象有地址值,如数组的每一个实体都对应地址。而首地址在栈中。
面向对象:
三个特征:封装、继承、多态
找对象、建立对象、使用对象、维护对象
类和对象的关系:
类就是对现实生活中事物的描述。
对象就是这类事物,实实在在存在个体。
class定义类,new出对象。
class Car
{
int num = 4;
void run()
{
System.out.println(".."+num);
}
}
Car c = new Car();//c为类类型变量
c.num = 5;//对象.对象成员
Car c1 = c;
c1.num = 6;//此时c.num也跟着改变,因为c的地址值赋值给了c1,c1和c指向同一块内存。
成员变量和局部变量:
成员变量作用于整个类中,局部变量作用于函数中
在内存中的位置,成员变量在堆内存中,因为对象的存在,才在内存中存在。局部变量在栈内存中。
匿名对象:
new Car().num = 5;//调用成员变量无意义
new Car().run();//调用方法有意义
使用方式一:当对对象的方法只调用一次时,可以用匿名对象来完成。若对一个对象进行多个成员调用,必须给这个对象起一个名字。
使用方式二:可以将匿名对象作为实际参数进行传递。
封装:
隐藏对象属性和实现细节,仅对外提供公共访问方式。
好处:提高复用性、安全性、便于使用
封装原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法。
private : 私有,权限修饰符
注意:私有仅仅是封装的一种表现形式。
构造函数:
特点:函数名和类名相同、不用定义返回值类型、不可以写return
作用:给对象进行初始化
class Person
{
Person()//构造函数
{
System.out.println("person run");
}
}
对象一建立就会调用与之对应的构造函数,构造函数可以用于给对象进行初始化。
构造函数只运行一次。
默认构造函数:
当一个类中没有定义构造函数时,系统会默认给该类加入一个空参数的构造函数。
构造代码块:
{
.....
}
作用:给对象进行初始化
对象一建立就运行,而且优先于构造函数执行
和构造函数的区别:
构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。
对象共性初始化方式。(针对不同的对象的构造函数)
this指针:
类中构造函数定义了与成员变量相同的局部变量,不会对成员变量操作,此时this.变量 = 变量可以解决这种问题。
this代表所调用该类的对象。
应用:
当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。
但凡本类功能内部使用了本类对象,都用this表示。
this关键字在构造函数间调用:
Person(string name)
{
this.name = name;
}
Person(string name, int age)
{
this(name);//构造函数间调用只能用this
this.age = age;
}
this语句只能放在构造函数的第一行
static 关键字:
静态:static
用法:是一个修饰符,用于修饰成员(成员变量,成员函数)
当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用,还可以直接被类名调用,类名.静态成员。
方法区、共享区、数据区
static特点:
1.随着类的加载而加载。也就是说静态会随着类的消失而消失,生命周期跟随类。
2.优先于对象存在。明确静态先存在,对象后存在。
3.被所有对象共享
4.可以直接被类名所调用
实例变量(成员变量)和类变量(静态变量)的区别:
1.存放位置。类变量随着类的加载而存在于方法区中。
实例变量随着对象的建立而存在于堆内存中。
2.生命周期。类变量生命周期最长,随着类的消失而消失。
实例变量生命周期随着对象的消失而消失。
静态使用注意事项:
1.静态方法只能访问静态成员
非静态方法既可以访问静态也可以访问非静态
2.静态方法中不可以定义this、super关键字
因为静态优先于对象存在,所以静态方法中不可以出现this。
3.主函数是静态的。主函数是一个特殊函数,作为程序入口,可以被jvm调用。
主函数的定义:public代表该函数访问的权限是最大的、static代表主函数随着类的加载已经存在、void没有具体的返回值、main不是关键字,但是是一个特殊的单词,被JVM识别、(String[] arr)函数的参数,参数类型是一个数组,该数组中的元素是字符串。字符串类型的数组。
主函数是固定格式的:jvm识别。
jvm在调用主函数时,传入的是new String[0];
静态有利有弊:
利:对对象的共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。可以直接被类名调用。
弊端:生命周期过长。访问出现局限性。(静态虽好,只能访问静态)
什么时候使用静态:
要从两方面下手,因为静态修饰的内容有成员变量和函数。
什么时候定义静态变量(类变量)?
当对象中出现共享数据时,该数据被静态所修饰。
对象中的特有数据要定义成非静态,存在于堆内存中。
什么时候定义静态函数?
当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义为静态的。
帮助文档的制作javadoc:
/**
这是一个...工具类,该类提供了...功能。
@author 张三
@version V1.1
*/
/**
获取最大值
@param arr 接收..数组
@return 会返回一个该数组中的最大值
*/
javadoc -d myhelp -author -version ArraryTool.java
静态代码块:
格式:
static
{
...
}
特点:随着类的加载而执行,只执行一次,并优先于主函数。
设计模式:
解决某一类问题最行之有效的方法。
java中23中设计模式:
单例设计模式:
解决一个类在内存只存在一个对象。
想要保证对象唯一。
1.为了避免其它程序过多建立该类对象,先禁止其他程序建立该类对象
2.还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
三步用代码体现?
1.将构造函数私有化
2.在类中创建一个本类对象。
3.提供一个方法可以获取到该对象。
对于事物该怎么描述还怎么描述,当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。
第一种方式:先初始化对象(饿汉式)
class Single
{
private Single(){}
private static Single s = new Single();
public static Single getInstance()
{
return s;
}
}
Single s1 = Single.getInstance();
Single s2 = Single.getInstance();
第二种方式:对象是方法被调用时才初始化,也叫作对象的延时加载(懒汉式)
class Single
{
private static Single s = null;
private Single(){}
public static Single getInstance()
{
if(s == null)
{
s = new Single();
}
return s;
}
}
开发一般用饿汉式。懒汉式存在小问题。
继承:
java只支持单继承,不支持多继承。
因为多继承容易带来安全隐患,当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪一个,但是java保留这种机制,并用另一种体现形式来完成表示。多实现。
java支持多层继承。
提高了代码的复用性。
让类与类之间产生了关系,有了这个关系,才有了多态的特性。
class Person
{
name、age
}
class Student extends Person
{
void study(){}
}
class Worker extends Person
{
void work(){}
}
如何使用一个继承体系中的功能?
想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。
通过了解共性功能,就可以知道该体系的基本功能。
那么这个体系已经可以基本使用了。
那么在具体调用时,要创建最子类的对象,一是因为父类可能不能创建对象,二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。
查阅父类功能,创建子类对象使用功能。
super.num指的是父类的变量。
若子类中出现非私有的同名成员变量时,子类要访问本类的变量,用this,子类要访问父类中的同名变量,用super。
子父类中的函数:当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。如同父类函数被覆盖。这种情况是函数的另一个特性:重写(覆盖)
重载:只看同名函数的参数列表。
重写:子父类方法要一模一样。
子父类的构造函数:
class fu
{
fu()
{
System.out.println("fu run");
}
}
class zi extends fu
{
zi()
{
//super();相当于隐藏了该语句
System.out.println("zi run");
}
}
在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句super();
为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
注意:super语句一定定义在子类构造函数的第一行。
子类的实例化过程:
结论:子类的所有构造函数,默认都会访问父类中空参数的构造函数。因为子类每一个构造函数内的第一行都有一句隐式super();
当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。
子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。
final关键字:
修饰符:
可以修饰类、函数、变量
被修饰的类不可以被继承,为了避免被继承,被子类复写功能。
被修饰的方法不可以被复写
被修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,也可以修饰局部变量。
抽象类:
abstract
抽象类的特点:
抽象方法一定在抽象类中。
抽象方法和抽象类都必须被abstract关键字修饰。
抽象类不可以用new创建对象,因为调用抽象方法没意义。
抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
abstract class student
{
abstract void study();
}
抽象类比一般类多了个抽象函数。
抽象类不可以实例化。
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
模板方法模式:
获取时间:System.currentTimeMillis();
abstract class GetTime
{
public final void getTime()
{
long start = System.currentTimeMillis();
runcode();
long end = System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
public abstract void runcode();
}
class SubTime extends GetTime
{
public void runcode()
{
for(int x = 0; x<4000; x++)
{
System.out.println(x);
}
}
}
class TemplateDemo
{
public static void main(String[] args)
{
SubTime gt = new SubTime();
gt.getTime();
}
}
什么是模板方法?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去,由该类的子类去完成。
接口:
初期理解:特殊的抽象类
当抽象类的