一.函数
a.定义格式:
返回类型 函数名(参数列表) {函数体}
b.为什么使用函数:
提高代码的复用性
c.参数列表:
函数的参数列表定义之后, 调用函数时传入的数据类型, 个数, 顺序都必须与参数列表匹配
注:
实参可以是形参的小类型,如:将byte数据传给fun(int i)是可以的
d.返回值:
定义函数时,必须定义函数的返回值类型.若是没有返回值,则定义成void.
当定义了函数的返回值类型,则使用return返回数据,而且必须保证数据类型一致.
使用return关键字可以用于返回一个数据,另外还有结束当前函数的作用.
如:
static int fun() {
.......
return int类型数据; //1.返回数据
}
static void fun(int i) {
if(i > 10)
return ; //2.结束功能
System.out.print(i);
}
注:
return的数据类型可以是函数上定义的类型的小类型,如:
static double fun() {
return 100; //这是可以的
}
二.函数重载-overload:
函数重载的条件:
1.方法名相同;
2.参数列表不同(具体包括参数个数,类型,顺序的不同);
注:
函数重载是不考虑返回值类型的!
三.函数重写-override:
函数重写的条件:
1.父类和子类的方法必须都是实例方法;
2.子类方法的方法名和参数列表必须和父类一样;子类的返回值类型与父类的相同(在1.5开始,子类的返回值类型可以是父类的返回值类型的子类)
3.子类方法的访问权限不能小于父类的访问权限;
4.子类方法抛出的异常与父类相同或是父类方法抛出异常的子集;
5.父类的方法在子类中必须是可见的.
四.运算符:
1.算术运算符:
+ -: 正负
+ -: 加减
* : 乘法
/ : 除法, 如: 10/3 结果为:3
% : 取模,
如:
a. 10%3 结果为:1
b. 取模运算的符号取决于被模数的符号:
10%3 结果为:1
10%-3 结果为:1
-10%3 结果为:-1
-10%-3 结果为:-1
前置++:自增, 如: int a=1;a=++a; 结果为:a=2
后置++:自增, 如: int a=1;a=a++; 结果为:a=1 (先取值,再自增)
前置--:自减, 同理++
后置--:自减, 同理++
+ : 字符串相加,即连接
如: System.out.print('A'+'B'); //自动提升int,相加,结果为:131
System.out.print("A"+"B"); //结果为:AB
注:
a.
int i=5;
int j=10;
若执行:System.out.println( i + (i++ + j));//结果是:20,原因:计算顺序是从左到右的,计算前会先确定出:5 + (5++ + 10)
若执行:System.out.println((i++ + j)+ i ); //结果是:21
b.算法: (x + (n-1)) / n
练习:有x个人,每个房间可以住6人,现在需要多少房间?
code:
return (x + 5) / 6;
2.赋值运算符:
+:
+=: i+=1;作用类似于:i=i+1; (注意:+=不会提升类型,如:byte b=1; b+=1; 编译正常)
-=:
*=:
/=:
%=:
注:
a. byte b = 1+1; //编译正常
b. byte b = 1; b+=1; //编译正常
c. byte b = 1; b=b++; //编译正常,且结果是: 1 (注意:自增操作也不会提升类型!)
d.
x=2,y=3,不需通过第三个变量交换值?
方法一:
x=x+y; x=5
y=x-y; y=5-3=2
x=x-y; x=5-2=3
方法二:
x=x^y;
y=x^y;
x=x^y;
方法三:
x = y + (y = x) - x;
方法四:
x = y^(y=x)^x;
3.比较运算符:
==(注意:区别于"=")
!=
<
>
<=
>=
instanceof:指左侧操作数的引用所指向的对象类型是否是右操作数(类或者接口)的类型
注意:
a.若某对象是一类的实例.即instanceof判断为true,那么这个对象肯定是那个类的父类的类型
Cat cat = new Cat();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof Animal);
b.不允许两侧是两个无关的类,否则会编译报错!
4.逻辑运算符:
&: 与,左右两边都为true, 结果才为true
|: 或,左右两边有一边为true, 结果就为true
&&: 短路与,与&运行结果相同, 但具有短路效果. 如果前半为false, 那么后半不执行
||: 短路或,和|运行结果相同, 但具有短路效果. 如果前半为true, 那么后半不执行
^: 异或,两边不同就是true, 相同就是false;
!: 非,原来是true结果就是false, 原来是false结果就是true
注意:
说出&与&&的区别?
答:首先说共同点:&和&&,是逻辑运算符,与,结果相同.
但&&具有短路效果,前半段是false时,结束判断.
另外,&,还可以作位运算符.
5.位运算符:
&:与,既可以作逻辑运算符,也可以作位运算符;
|:或,既可以作逻辑运算符,也可以作位运算符;
^:异或,既可以作逻辑运算符,也可以作位运算符; (注意:一个数异或同一个数两次,结果还是其本身!)
注:
求5 & 8 = ?
5: 0000 0101
8: 0000 1000
&
0000 0000 =0
移位运算符:
<<:左移,低位补"0"
>>:右移,负数的话,高位补"1";正数的话,高位补"0"
>>>:无符号左移,高位补"0";所以,负数移位肯定是正的
注:
a.计算48 << -7 (对于"负位数"来说,处理方法:提取该右操作数的低5位,实际就是将右操作数与0x1f进行与运算!)
解答:
-7 : 1000 0000-0000 0000-0000 0000-0000 0111(原码)
1111 1111-1111 1111-1111 1111-1111 1000
1111 1111-1111 1111-1111 1111-1111 1001(补码)
低五位: 11001 = 25
即为:
计算48 << 25的结果!!!!!!!!!!!
b.-16 >> 1 = ?
-16: 1000 0000-0000 0000-0000 0000-0001 0000(原码)
取反(不含符号位): 1111 1111-1111 1111-1111 1111-1110 1111
+1: 1111 1111-1111 1111-1111 1111-1111 0000(补码)
>>1(负数,高位补"1"): 1111 1111-1111 1111-1111 1111-1111 1000
再求补码,先取反(不含符号位):
1000 0000-0000 0000-0000 0000-0000 0111
再+1: 1000 0000-0000 0000-0000 0000-0000 1000 = -8
五.异或的运用:
文件加密
代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
class Encrypt {
private static final int PASSWORD = 0x12345678;
private static final String SUFFIX = ".enc";
public void doEncrypt(String path) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
File file = new File(path);
File newFile = new File(path+SUFFIX);
fis = new FileInputStream(file); //FileNotFoundException
fos = new FileOutputStream(newFile); //FileNotFoundException
byte [] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1) { //IOException
for(int i = 0;i<len;i++)
{
buf[i]=(byte)(buf[i]^PASSWORD);
}
fos.write(buf,0,len); //IOException
}
}
catch(FileNotFoundException e) {
throw new RuntimeException("文件不存在,请重试!");
}
catch(IOException e) {
throw new RuntimeException("文件读取异常!");
}
finally {
try {
if(fis!=null)
fis.close();
}catch(Exception e ) {
throw new RuntimeException("文件读取流异常!");
}
try {
if(fos!=null)
fos.close();
}catch(Exception e) {
throw new RuntimeException("文件存储流异常!");
}
}
}
public void doDecrypt(String path) {
int index = path.lastIndexOf(SUFFIX);
if(index!=(path.length()-SUFFIX.length())) {
System.out.println("文件类型不正确!请重试!");
return;
}
FileInputStream fis = null;
FileOutputStream fos = null;
try {
File file = new File(path);
File newFile = new File(path.substring(0,index));
fis = new FileInputStream(file); //FileNotFoundException
fos = new FileOutputStream(newFile); //FileNotFoundException
byte [] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1) { //IOException
for(int i = 0;i<len;i++)
{
buf[i]=(byte)(buf[i]^PASSWORD);
}
fos.write(buf,0,len); //IOException
}
}
catch(FileNotFoundException e) {
throw new RuntimeException("文件不存在,请重试!");
}
catch(IOException e) {
throw new RuntimeException("文件读取异常!");
}
finally {
try {
if(fis!=null)
fis.close();
}catch(Exception e ) {
throw new RuntimeException("文件读取流异常!");
}
try {
if(fos!=null)
fos.close();
}catch(Exception e) {
throw new RuntimeException("文件存储流异常!");
}
}
}
public static void main(String [] args) {
Encrypt e = new Encrypt();
if(args.length != 2) {
System.out.println("参数输入错误!请重新输入!");
return;
}
if(args[0].equalsIgnoreCase("encrypt"))
e.doEncrypt(args[1]);
else if(args[0].toUpperCase().equals("DECRYPT")) {
e.doDecrypt(args[1]);
}
}
}