Java学习笔记(三)—— 基础语法

    看了一些网上的资料发现Java和c的语法是类似的,也有一些不同,之前看的那本书讲到输入输出时已经是两百多页了,,,果断换书。看的这本《Java面向对象程序设计》,目前自我感觉良好。总结如下。

适合有C语言基础和面向对象编程概念。

 

一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。

  • 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
  • :类是一个模板,它描述一类对象的行为和状态。
  • 方法:方法就是行为,一个类可以有很多方法。逻辑运算、数据修改以及所有动作都是在方法中完成的。
  • 实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。

 

编写Java程序时,应注意以下几点:

  • 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的。
  • 类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
  • 方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
  • 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记Java是大小写敏感的),文件名的后缀为.java。(如果文件名和类名不相同则会导致编译错误)。
  • 主方法入口:所有的Java 程序由public static void main(String []args)方法开始执行。

 

标识符

Java标识符比c多了一个‘$’,并且这个符号可以作为标识符的开头,并且,Java的字符集为Unicode,就是说,这里面的字符都可以作为Java的‘字母’,也包括汉字,如:‘$surk’、‘ab$3d’、‘_ad2$’,‘这是一个标识符’ 。

 

Java中变量主要有:局部变量、类变量(静态变量)、成员变量(非静态变量)。

 

Java的八种基本类型:

 分  类

数据类型

关键字

占用字节

缺省数值

取 值 范 围

整型类

字节型

byte

1

0

-2^7~2^7-1

短整型

short

2

0

-2^15~2^15-1

整型

int

4

0

-2^31~2^31-1

长整型

long

8

0L

-2^63~2^63-1

文本类

字符型

char

2

′\u 0000′

′\u 0000′ ~ ′\u FFFF′

浮点类

浮点型

float

4

0.0F

-3.4E38~3.4E38

双精度型

double 

8

0.0D

-1.7E308~1.7E308

逻辑类

逻辑型

boolean

1

False

True、False

 

Java中默认的整数类型是int,如果要定义为long ,则要在数值后加上L或者l

默认的浮点型是双精度浮点,如果要定义float,则要在数值后面加上f或者F

一个字节等于8位,1个字节等于256个数。

一个英文字母或者阿拉伯数字占一个字节

一个汉字占2个字节

 

关键字

下面列出了Java 关键字。这些保留字不能用于常量、变量、和任何标识符的名称。

类别 关键字 说明
访问控制 private 私有的
protected 受保护的
public 公共的
类、方法和变量修饰符 abstract 声明抽象
class
extends 扩允,继承
final 最终值,不可改变的
implements 实现(接口)
interface 接口
native 本地,原生方法(非Java实现)
new 新,创建
static 静态
strictfp 严格,精准
synchronized 线程,同步
transient 短暂
volatile 易失
程序控制语句 break 跳出循环
case 定义一个值以供switch选择
continue 继续
default 默认
do 运行
else 否则
for 循环
if 如果
instanceof 实例
return 返回
switch 根据值选择执行
while 循环
错误处理 assert 断言表达式是否为真
catch 捕捉异常
finally 有没有异常都执行
throw 抛出一个异常对象
throws 声明一个异常可能被抛出
try 捕获异常
包相关 import 引入
package
基本类型 boolean 布尔型
byte 字节型
char 字符型
double 双精度浮点
float 单精度浮点
int 整型
long 长整型
short 短整型
变量引用 super 父类,超类
this 本类
void 无返回值
保留关键字 goto 是关键字,但不能使用
const 是关键字,但不能使用
null

 

转义字符

转义符是指一些有特殊含义的、很难用一般方式表达的字符,如回车、换行等。所有的转义符以反斜线(\)开头,后面跟着一个字符来表示某个特定的转义符,如下表所示。

引用方法

含义

\b

退格

\t

水平制表符Tab

\n

换行

\f

表格符

\r

回车

\'

单引号

\"

双引号

\\

反斜杠

 

注释

Java支持三种注释:

  • 行注释://注释内容
  •  段注释:/*注释内容*/
  • 文档注释:/**注释内容*/

 

继承

在Java中,一个类可以由其他类派生。如果你要创建一个类,而且已经存在一个类具有你所需要的属性或方法,那么你可以将新创建的类继承该类。

利用继承的方法,可以重用已存在类的方法和属性,而不用重写这些代码。被继承的类称为超类(super class),派生类称为子类(subclass)。

 

接口

在Java中,接口可理解为对象间相互通信的协议。接口在继承中扮演着很重要的角色。

接口只定义派生要用到的方法,但是方法的具体实现完全取决于派生类。

 

Java编程规范

  • package的命名: package 的名字由全部小写的字母组成,例如:com.runoob。
  • class和interface的命名: class和interface的名字由大写字母开头而其他字母都小写的单词组成,例如:Person,RuntimeException。
  • class变量的命名: 变量的名字用一个小写字母开头,后面的单词用大写字母开头,例如:index,currentImage。
  • class 方法的命名: 方法的名字用一个小写字母开头,后面的单词用大写字母开头,例如:run(),getBalance()。
  • staticfinal变量的命名: static final变量的名字所有字母都大写,并且能表示完整含义。例如:PI,PASSWORD。
  • 参数的命名: 参数的名字和变量的命名规范一致。
  • 数组的命名: 数组应该总是用这样的方式来命名:byte[] buffer。
  • package语句:由于Java编译器为每个类生成一个字节码文件,且文件名与类名相同因此同名的类有可能发生冲突。为了解决这一问题,Java提供包来管理类名空间,包实 提供了一种命名机制和可见性限制机制。

 

 

 

输入输出

 

Scanner

输入时可以用Scanner来创建对象:

Scanner reader = new Scanner(System.in);

然后reader对象调用方法next(),nextBoolean(),nextByte(),nextDouble(),nextInt(),nextFloat(),nextShort(),nextLong(),读取在命令行输入的各种基本类型数据。如:

int a=reader.nextInt(),b=reader.nextInt();

 

System.out.println() 和 System.out.print()

输出时System.out.println()和System.out.print()可以输出字符、表达式的值,区别在于前者输出时会自动输出一个换行,后者不会,允许使用并置符号“+”来连接前后。如:

int x=1;
System.out.println("x="+x);    //输出x=1

 

格式化输出System.out.printf()

Java还有类似c语言的printf函数用来输出带有格式控制的数据,用法和c相同,特别的,Java的double类型使用“%f”,如:

System.out.printf("%d %f\n",a,b);

 

多实例输入

使用hasNext()来判断有没有输入,相当于c中的scanf()!=EOF,类似的还有hasNextInt(),hasNextDouble()等,用来判断有无int,double等类型的输入。

Scanner in = new Scanner(System.in);
while(in.hasNext()) {
    int a = in.nextInt();
    int b = in.nextInt();
    System.out.println(a + b);
}

 

 

 

数组

Java的数组声明和c也差不多,有两种形式:

int[] a;
int a[];

 

声明不等于创建,变量必须被创建才可以被使用

声明和创建分为两步,这也是Java和c的区别,c在声明变量时自动为其分配内存,Java则需要使用new关键字来为变量分配内存。

特别的,Java不允许在方括号中指定元素个数,上面的语句只是声明一个数组a,并未分配内存。所以还须采用new创建,

int a[];
a=new int[10];
		
int a=new int[10];

 

初始化

上面是两种创建方法,这样一维数组就可以使用了,也可以在声明数组时初始化,初始化方面和c差异不大,如:

char ac[]= {'a','v'};

 

二维数组

二维数组的使用同一维数组,只是多了一个方括号,特别的,二维数组相当于多个一维数组组成,这些一维数组长度不必相等,

int x[][] = new int[2][];
x[0]=new int[10];
x[1]=new int[5];
//或
int x[][]=new int[2][3];

Java还允许这样使用

int size=30;
int x[]=new int[size];

特别的,Java中数组属于引用类型

x=y;	//这样会把x所指内存空间释放掉,使得x和y指向同一块内存空间,此时x[]={1,2},这时使用x或y实际上是一样的,改变其中一个,另一个也会改变。

 

遍历数组

一种是:同c一样的

int y[]= {3,0,1};
for(int i = 0;i < y.length;i++) {
	System.out.println(y[i]);	//3,0,1
}

另一种是:Java专门的对于遍历数组的优化使用

int y[]= {3,0,1};
for(int i:y) {
	System.out.println(i);	//3,0,1
}

注意:i的类型应该和数组y的类型相同,而且下面这种写法是错误的,

int y[]= {3,0,1};
int i=0;    //错误
for(i:y) {
	System.out.println(i);
}

变量i必须重新声明,不能使用已有的变量。

 

clone()的使用

那么如何复制数组呢,可以使用循环来复制,也可以使用clone(),如:

char ac[]= {'a','v'};
char ax[]= {'b'};
ac=ax.clone();
System.out.println(ax);    //b
System.out.println(ac);    //b

 

length的使用

对于一维数组x[10],x.length=10,即一维数组的长度,对于二维数组x[2][3],x.length=2,即二维数组中一维数组的个数。

 

Arrays.toString()的使用

数组a[2]={1,2}; Array.toString(a)可以将整型转换为字符型,需import java.util.*,如:

int a[]= {1,2};
System.out.println(Arrays.toString(a));    //[1, 2]

 

copyOf()和copyOfRange()

int y[]= {1,2};
int z[]=Arrays.copyOf(y,3);	//z[]={1,2,0};
int z[]=Arrays.copyOf(y,1);	//z[]={1};
int y[]= {1,2};
int z[]=Arrays.copyOfRange(y,0,3);	//z[]={1,2,0};
int z[]=Arrays.copyOfRange(y,0,2);	//z[]={1,2};

其中,copyOf(y,newLength)为从y中0位置开始复制长度为newLength,若newLength的值大于原数组则填充默认值。

copyOfRange(y,from,to)为从y中from开始到to-1的位置,若to的值大于原数组则填充默认值。

 

Arrays.sort()

int y[]= {3,0,1};
Arrays.sort(y);	//y[]={0,1,3};

默认升序排序,貌似没有降序的,,,,倒着看就行,问题不大。

 

Arrays.binarySearch()

Arrays.binarySearch(double[] a,double number)可以查找参数number是否在指定数组中,其中a必须是已排好序的数组,若找到则返回位置,否则返回负数。

int y[]= {3,0,1};
Arrays.sort(y);	//y[]={0,1,3};
int index=Arrays.binarySearch(y,3);	//index=2

 

equals()

Arrays.equals()用来比较两个数组是否相等,返回逻辑值true或false,如:

int x[]= {5};
int y[]= {1,2};
System.out.println(Arrays.equals(x,y));    //false

 

 

 

String类

 

在Java中String为不可变对象,可以如此定义一个字符串:String s = "abc";,常见的还有两种构造方法,其中第二种String(char a[],startIndex,count),两个参数分别为字符数组的起始位置和从该位置开始截取的长度。

char ax[]= {'b','d','c'};
String s = new String(ax);
System.out.println(s);		//bdc
String h = new String(ax,1,2);
System.out.println(h);		//dc

 

substring(from,to)

可以提取字符串从from到to-1的字符,如:

String T="hello";
System.out.println(T.substring(0,3));	//hel

 

重载了"+"

字符串和字符串之间可以用"+"拼接,

String T="hello";
String Y="world";
String U=T+Y;
System.out.println(U);	//helloworld

 

join()

如果需要把多个字符串放在一起,用一个定界符分隔,可以使用静态方法join方法,如:

String S=String.join("!","s","b","a","g");
System.out.println(S);    //s!b!a!g

 

s.equals(t)

检测字符串是否相等使用s.equals(t),其中s,t即可以是字符串常量,也可以是字符串变量。

String T="hello";
String Y="world";
System.out.println(T.equals(Y));	//false

如果用==比较的话,实际比较的是两个字符串的地址是否相同。

 

length()

确定字符串长度用length()方法,(数组的length是属性,而非方法)。

 

toCharArray()

用来把String类转换为字符数组,这样可以进行对字符串进行"数组名+下标"式的修改,

String sa="hello";
System.out.println(sa.toCharArray());	//hello
char sb[];
sb=sa.toCharArray();
sb[1]='a';
System.out.println(sb[1]);	//a

 

String.valueOf()

用来把字符数组转换为字符串,也可以把数值转换为字符串 。

String sa;
char sb[]= {'a','b','c'};
sa=String.valueOf(sb);	
System.out.println(sa);	//abc

 

Long类中的toString(long i,int p)

这个方法可以返回整数i的p进制表示。

System.out.println(Long.toString(10,2));	//1010

 

compareTo()

也可以使用compareTo()来比较字符串是否相等,和C语言中的comcmp()使用方法一样,不在解释。

 

 

 

StringBuffer 和 StringBuilder

这两个可以实现对字符串的增删改。

String 长度大小不可变

StringBuffer 和 StringBuilder 长度可变

StringBuffer 线程安全 StringBuilder 线程不安全

StringBuilder 速度快

通常在99.99%的情况下可以选择用StringBuilder,

 

append(),insert(),delete(),replace()

StringBuilder s = new StringBuilder();
s.append("abc");
System.out.println(s);	//abc
s.insert(1,"qwer");
System.out.println(s);	//aqwerbc
s.delete(1,5);
System.out.println(s);	//abc
s.replace(0,2,"e");
System.out.println(s);	//ec

 

 

 

网上淘来几道面试题,,,,关于常量池的

面试题一:

String s1 = "abc";            // 常量池
String s2 = new String("abc");     // 堆内存中
System.out.println(s1==s2);        // false两个对象的地址值不一样。
System.out.println(s1.equals(s2)); // true

面试题二:

String s1="a"+"b"+"c";
String s2="abc";
System.out.println(s1==s2);
System.out.println(s1.equals(s2));

java 中常量优化机制,编译时 s1 已经成为 abc 在常量池中查找创建,s2 不需要再创建。

面试题三:

String s1="ab";
String s2="abc";
String s3=s1+"c";
System.out.println(s3==s2);         // false
System.out.println(s3.equals(s2));  // true

先在常量池中创建 ab ,地址指向 s1, 再创建 abc ,指向 s2。对于 s3,先创建StringBuilder(或 StringBuffer)对象,通过 append 连接得到 abc ,再调用 toString() 转换得到的地址指向 s3。故 (s3==s2) 为 false

 

Java:String、StringBuffer 和 StringBuilder 的区别

String:字符串常量,字符串长度不可变。Java中String 是immutable(不可变)的。用于存放字符的数组被声明为final的,因此只能赋值一次,不可再更改。

StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。Java.lang.StringBuffer 线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。

StringBuilder:字符串变量(非线程安全)。在内部 StringBuilder 对象被当作是一个包含字符序列的变长数组。

基本原则:

  • 如果要操作少量的数据用 String ;
  • 单线程操作大量数据用StringBuilder ;
  • 多线程操作大量数据,用StringBuffer。

 

参考文章:打开链接

 

 

你可能感兴趣的:(Java)