目录,更新ing,学习Java的点滴记录
目录放在这里太长了,附目录链接大家可以自由选择查看--------Java学习目录
语句块
- 语句块(有时叫做复合语句),是用花括号扩起的任意数量的简单 Java 语句。块确定
了局部变量的作用域。块中的程序代码,作为一个整体,是要被一起执行的。块可以被嵌套在另一个块中,但是不能在两个嵌套的块内声明同名的变量。语句块可以使用外部的变量,而外部不能使用语句块中定义的变量
,因为语句块中定义的变量作用域只限于语句块。 - 示例
方法
- 许多程序设计语言(像C和C++)用
函数
这个术语来描述命名子程序;而在Java里却常用方法
这个术语表示"做某些事情的方法". - Java的
方法
决定了一个对象能够接收什么样的消息.方法的基本组成部分
包括:名称,参数,返回值和方法体
- 方法声明基本形式:
返回类型
描述的是在调用方法之后从方法返回的值.参数列表
给出了要传给方法的信息的类型和名称.方法名和参数列表(合起来被称为"方法签名")唯一地标识出某个方法. - Java中的方法只能作为类的一部分来创建,除静态方法外,方法只能通过对象才能被调用,且这个对象必须执行这个方法的调用.如果视图在某个对象上调用并不属于它的方法,那么在编译时就会得到错误信息.
- 方法调用形式:
对象名.方法名(实参列表) - 方法详细说明
形式参数
:在方法声明时用于接收外界传入的数据----(int a,int b)
实参
调用方法时实际传给方法的数据-----(1,2)
返回值
:方法在执行完毕后返还给调用它的环境的数据-----main方法中打印函数接收到的数据是3
返回值类型
:实现约定的返回值的数据类型,如无返回值,必须指定为void------testMethod方法的返回值类型为int - 调用方法的注意点
(1) 实参的数目,数据类型和次数必须和所调用的方法声明的形式参数列表匹配
(2)return语句终止方法的运行并返回数据
(3)Java中进行方法调用传递参数时,遵循值传递的原则(传递的都是数据的副本)
当方法参数为基本数据类型时,是将外部变量值拷贝到局部变量中而进行逻辑处理的,故方法是不能修改原基本变量的
对于引用类型的方法参数,会将外部变量的引用地址,复制一份到方法的局部变量中,两个对象指向同一个地址。所以如果通过操作副本引用的值,修改了引用地址的对象,此时方法以外的引用此地址对象也会被修改。
方法的重载
- 在日常生活中,相同的词可以表达多种不同的含义—他们被"重载"了.特别是含义之间差别很小时,这种方式十分有用.可以说"清晰衬衫,清洗车,清洗狗".但如果硬要这样说就显得很愚蠢:“以洗衬衫的方式洗衬衫,以洗车的方式洗车”.这是因为听众根本不需要对所执行的动作做出明确的区分.大多数人类语言都具有很强的"冗余性".
- 提前讲一点关于类的知识:在Java(和C++)里,构造器时强制重载方法名的一个原因.既然构造器的名字已经由类名所确定,就只能有一个构造器名.那么想用多种方式创建一个对象该怎么办呢?为了让方法名相同而形式参数不同的构造器同时存在,必须用到方法重载.
方法的重载
是指一个类中可以定义多个方法名相同
,但参数不同
的方法。 调用时,会根据不同的参数自动匹配
对应的方法。- 构成方法重载的条件:
形参类型、形参个数、形参顺序不同
雷区
只有返回值不同
不构成方法的重载
只有形参的名称
不同,不构成方法的重载- 示例
package com.test;
public class Main {
public static void main(String[] args) {
System.out.println(add(3, 5));// 8
System.out.println(add(3, 5, 10));// 18
System.out.println(add(3.0, 5));// 8.0
System.out.println(add(3, 5.0));// 8.0
// 我们已经见过的方法的重载
System.out.println(); //0个参数
System.out.println(1); //参数是1个int
System.out.println(3.0); //参数是1个double
}
/**
* 求和的方法
*/
public static int add(int n1, int n2) {
int sum = n1 + n2;
return sum;
}
// 方法名相同,参数个数不同,构成重载
public static int add(int n1, int n2, int n3) {
int sum = n1 + n2 + n3;
return sum;
}
// 方法名相同,参数类型不同,构成重载
public static double add(double n1, int n2) {
double sum = n1 + n2;
return sum;
}
// 方法名相同,参数顺序不同,构成重载
public static double add(int n1, double n2) {
double sum = n1 + n2;
return sum;
}
//编译错误:只有返回值不同,不构成方法的重载
// public static double add(int n1, int n2) {
// double sum = n1 + n2;
// return sum;
// }
//编译错误:只有参数名称不同,不构成方法的重载
// public static int add(int n2, int n1) {
// double sum = n1 + n2;
// return sum;
// }
}
- 涉及基本类型的重载(可能复杂一点,可跳过)
基本类型能从一个"较小"的类型自动提升至一个"较大"的类型,此过程一旦牵涉到重载,可能会造成一些混淆.请看下面的例子,代码可复制粘贴运行
package com.test;
public class Main {
void f1(char x){
System.out.print("f1(char)");
}
void f1(byte x){
System.out.print("f1(byte)");
}
void f1(short x){
System.out.print("f1(short)");
}
void f1(int x){
System.out.print("f1(int)");
}
void f1(long x){
System.out.print("f1(long)");
}
void f1(float x){
System.out.print("f1(float)");
}
void f1(double x){
System.out.print("f1(double)");
}
void f2(byte x){
System.out.print("f2(byte)");
}
void f2(short x){
System.out.print("f2(short)");
}
void f2(int x){
System.out.print("f2(int)");
}
void f2(long x){
System.out.print("f2(long)");
}
void f2(float x){
System.out.print("f2(float)");
}
void f2(double x){
System.out.print("f2(double)");
}
void f3(short x){
System.out.print("f3(short)");
}
void f3(int x){
System.out.print("f3(int)");
}
void f3(long x){
System.out.print("f3(long)");
}
void f3(float x){
System.out.print("f3(float)");
}
void f3(double x){
System.out.print("f3(double)");
}
void f4(int x){
System.out.print("f4(int)");
}
void f4(long x){
System.out.print("f4(long)");
}
void f4(float x){
System.out.print("f4(float)");
}
void f4(double x){
System.out.print("f4(double)");
}
void f5(long x){
System.out.print("f5(long)");
}
void f5(float x){
System.out.print("f5(float)");
}
void f5(double x){
System.out.print("f5(double)");
}
void f6(float x){
System.out.print("f6(float)");
}
void f6(double x){
System.out.print("f6(double)");
}
void f7(double x){
System.out.print("f7(double)");
}
void testConstVal(){
System.out.print("5: ");
f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5);
System.out.println();
}
void testChar(){
char x = 'x';
System.out.print("char: ");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
System.out.println();
}
void testByte(){
byte x = 0;
System.out.print("byte: ");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
System.out.println();
}
void testShort(){
short x = 0;
System.out.print("short: ");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
System.out.println();
}
void testInt(){
int x = 0;
System.out.print("int: ");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
System.out.println();
}
void testLong(){
long x = 0;
System.out.print("long: ");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
System.out.println();
}
void testFloat(){
float x = 0;
System.out.print("float: ");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
System.out.println();
}
void testDouble(){
double x = 'x';
System.out.print("double: ");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
System.out.println();
}
public static void main(String[] args) {
Main main = new Main();
main.testConstVal();
main.testChar();
main.testByte();
main.testInt();
main.testLong();
main.testFloat();
main.testDouble();
}
}
可以发现,常数值5倍当做int值处理,如果有某个重载的方法接收int型参数,他就会被调用.至于其他情况,如果传入的数据类型(实际参数类型)小于方法中声明的形式参数类型,实际数据类型就会被提升.char型略有不同,如果无法找到恰好接受char参数的方法,就会把char直接提升至int型.如果传入的实际参数大于重载方法声明的形式参数,就必须得通过类型转换,否则编译器报错
递归结构
- 递归是一种常见的解决问题的方法,即把问题逐渐简单化。递归的基本思想就是
自己 调用自己
,一个使用递归技术的方法将会直接或者间接的调用自己。 - 利用递归可以用简单的程序来解决一些复杂的问题。比如:斐波那契数列的计算、汉诺 塔、快排等问题。
递归组成部分
定义递归头:什么时候不调用自身方法。如果没有头,将陷入死循环,也就是递归的结束条件。
什么时候需要调用自身方法- 示例:递归求n!
- 调用图解
- 递归的优缺点:简单的程序是递归的优点之一。但是递归调用会
占用大量的系统堆栈,内存耗用多
,在递归调用层次多时速度要比循环慢的多,所以在使用递归时要慎重。 - 注意点:
任何能用递归解决的问题也能使用迭代解决
。当递归方法可以更加自然地反映问题,并 且易于理解和调试,并且不强调效率问题时,可以采用递归
在要求高性能的情况下尽量避免使用递归,递归调用既花时间又耗内存