java 笔记一

一、基础原理

1、java跨平台的原理?

java在操作系统上加入了jvm虚拟机,程序运行在jvm上,jvm会自动根据不同操作系统将相同的.class字节码解释成不同的机器码

2、JDK、JRE、JVM的区别和联系?

JDK(java development kit) >JRE(java runtime enviroment) >JVM(java virtual machine).

JDK用于开发Java程序,JRE是Java运行环境; JVM是JRE的子集,JRE是JDK的子集。

3、java程序的开发和执行过程

编写源文件->编译源文件(使用编译器javac)->字节码->执行字节码(使用解释器java)

二、java数据类型

引用数据类型的大小统一为4个字节,记录的是其引用对象的地址!

float类型赋值时必须需要添加后缀F/f。没有后缀F/f的浮点数值默认为double类型。

浮点类型float,double的数据不适合在不容许舍入误差的金融计算领域。如果需要进行不产生舍入误差的精确数字计算,需要使用BigDecimal类。

  char 类型用来表示在Unicode编码表中的字符。Unicode编码被设计用来处理各种语言的文字,它占2个字节,可允许有65536个字符。

在Java中使用单引号来表示字符常量。例如’A’是一个字符,它与”A”是不同的,”A”表示含有一个字符的字符串。

boolean类型有两个常量值,true和false,在内存中占一位(不是一个字节)。

i ++:先进行赋值,再进行i+1操作; ++i:先进行i+1,再进行赋值。

逻辑与、逻辑或、逻辑非的优先级一定要熟悉!(逻辑非>逻辑与>逻辑或)。如,a||b&&c的运算结果是:a||(b&&c),而不是(a||b)&&c 。

三、控制语句

顺序、选择(if、switch)、循环

1、if  →  else if  → else

2、switch

当布尔表达式是等值判断的情况,可以使用if → else if → else多选择结构或者switch结构;如果布尔表达式区间判断的情况,则只能使用if → else if → else多选择结构。

switch语句中case标签在JDK1.5之前必须是整数(long类型除外)或者枚举,不能是字符串,在JDK1.7之后允许使用字符串(String)

3、while及do while

4、for循环

for(;;)与while(true)均表示无限循环;

5、break 和 continue

break 用于强行退出循环,不执行循环中剩余的语句。打破了最小封闭for或while循环。

continue 用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。

注意:

1. continue用在while,do-while中,continue 语句立刻跳到循环首部,越过了当前循环的其余部分。

2. continue用在for循环中,跳到for循环的迭代因子部分。

带标签的break 和 continue!!!

标签”是指后面跟一个冒号的标识符,例如:“label:”。对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。

6、方法

 方法就是一段用来完成特定功能的代码片段,类似于其它语言的函数。方法用于定义该类或该类的实例的行为特征和功能实现。 方法是类和对象行为特征的抽象。

如果方法前不加static则内存会放在堆?因此需要new一个对象才能使用,而使用static才会放在方法区,不需要new直接使用。

 方法的重载是指一个类中可以定义多个方法名相同,但参数不同的方法。 调用时,会根据不同的参数自动匹配对应的方法。 重载的方法,实际是完全不同的方法,只是名称相同而已!

public class Temp {
	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;
    }  
}

  

7、递归

递归的基本思想就是“自己调用自己”,一个使用递归技术的方法将会直接或者间接的调用自己。

递归结构包括两个部分:

      1.定义递归头。解答:什么时候不调用自身方法。如果没有头,将陷入死循环,也就是递归的结束条件。

      2.递归体。解答:什么时候需要调用自身方法。

public class Temp {
    public static void main(String[] args) {
        long d1 = System.currentTimeMillis();  
        System.out.printf("%d阶乘的结果:%s%n", 10, factorial(10));
        long d2 = System.currentTimeMillis();
        System.out.printf("递归费时:%s%n", d2-d1);  //耗时:32ms
        
        long d3 = System.currentTimeMillis();
        int a = 10;
        int result = 1;
        while (a > 1) {
            result *= a * (a - 1);
            a -= 2;
        }
        long d4 = System.currentTimeMillis();
        System.out.println(result);
        System.out.printf("普通循环费时:%s%n", d4 - d3);
    }
    /** 求阶乘的方法*/
    static long  factorial(int n){
        if(n==1){//递归头
            return 1;
        }else{//递归体
            return n*factorial(n-1);//n! = n * (n-1)!
        }
    }
}

递归的缺陷

      简单的程序是递归的优点之一。但是递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时速度要比循环慢的多,所以在使用递归时要慎重。

         任何能用递归解决的问题也能使用迭代解决。当递归方法可以更加自然地反映问题,并且易于理解和调试,并且不强调效率问题时,可以采用递归;在要求高性能的情况下尽量避免使用递归,递归调用既花时间又耗内存。

// 课后题目
import java.util.Scanner;
public class Temp {
	public static void main(String[] args) {
		//1. 从键盘输入某个十进制整数数,转换成对应的二进制整数并输出。
		System.out.println("请输入一个十进制整数:");
		Temp methods = new Temp();
		int temp1 = methods.decimalConvertBinal(1, 0);	//临时存储返回值
		System.out.println("二进制结果为:" + temp1);
		
		
		//2. 编程求:∑1+∑2+……+∑100。
		int temp2 = methods.totalNum();					//temp2存储返回值
		System.out.println("∑1+∑2+……+∑100 = " + temp2);
		
		
		//3.编写递归算法程序:一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求数列的第40位数是多少。
		
		System.out.println("第40位数字是:" + methods.sequence(40));
		
	}

/*
 * 第一题方法
 * 十进制转换为二进制方法
 */
	int decimalConvertBinal(int i,int changeNum) {		//changeNum为二进制数,此方法返回值为二进制
		Scanner scanner = new Scanner(System.in);
		int num = scanner.nextInt();
		for(;;) {
			if(num == 0) {
				break;
			}
			else {		
				int remainNum = num % 2;		//余数
				num = num / 2;					//以商作为被除数
				changeNum += remainNum * i;
				i = i * 10;
			}
		}
		return changeNum;
	}
	
	
	/*
	 * 第二题方法
	 * 求和方法
	 */
	int totalNum() {
		int sum = 0;
		for(int j = 1;j <= 100;j++) {
			for(int i = 1;i <= j;i++) {
				sum += i;
			}
		}
		return sum;
	}
	
	
	/*
	 * 第三题方法
	 * 数列递归方法
	 */
	int sequence(int num) {
		if(num == 1 || num == 2) {
			return 1;
		}else {
			return (sequence(num - 1) + sequence(num - 2));
		}
	}

}

四、类和对象

1、基本概念 

1.对象是具体的事物;类是对对象的抽象;

2.类可以看成一类对象的模板,对象可以看成该类的一个具体实例。

3.类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法。

//创建一个电脑类
class Computer{
	String brand;
}

public class Stu {
	//fields 属性
	int id;
	int age;
	String sname;
	Computer comp;
	
	//方法
	void study() {
		System.out.println("姓名:"+sname+"\n"
				+"学号: "+id+"\n"
				+"年龄: "+age+"\n"
				+"电脑:"+comp.brand);
	}
	
	//构造方法
	Stu() {
	}
	
	public static void main(String[] args) {
		Stu xm = new Stu(); //创建一个学生对象
		Computer dn = new Computer(); //创建一个电脑对象
		dn.brand = "联想";
		xm.comp = dn; //小明学生的电脑是上面创建的电脑对象
		xm.id = 211;
		xm.age = 18;
		xm.sname = "小明";
		xm.study();
	}
}

 

2、构造方法

 构造器也叫构造方法(constructor),用于对象的初始化。构造器是一个创建对象时被自动调用的特殊方法,目的是对象的初始化。

/**
1. 定义一个“点”(Point)类用来表示二维空间中的点(有两个坐标)。要求如下:

  (1) 可以生成具有特定坐标的点对象。

  (2) 提供可以设置坐标的方法。

  (3)提供可以计算该“点”距另外一点距离的方法。
*/
class Point {
    double x, y;
    //构造方法,创建对象时被自动调用;用于初始化对象
    public Point(double _x, double _y) {
        x = _x;
        y = _y;  
    }
    //计算距离的方法
    public double getDistance(Point p) {
        return Math.sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));
    }
}
public class TestConstructor {
    public static void main(String[] args) {
        Point p = new Point(3.0, 4.0);//创建一个对象,初始点为3.0,4.0
        Point origin = new Point(0.0, 0.0);
        System.out.println(p.getDistance(origin));
    }
}

3、内存分析

Java虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area。

栈的特点如下:

  1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)

  2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)

  3. 栈属于线程私有,不能实现线程间的共享!

  4. 栈的存储特性是“先进后出,后进先出”

  5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!

堆的特点如下:

  1. 堆用于存储创建好的对象和数组(数组也是对象)

  2. JVM只有一个堆,被所有线程共享

  3. 堆是一个不连续的内存空间,分配灵活,速度慢!

方法区(又叫静态区)特点如下:

  1. JVM只有一个方法区,被所有线程共享!

  2. 方法区实际也是堆,只是用于存储类、常量相关的信息!

  3. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)。

4、this

this的本质就是“创建好的对象的地址”! 由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表“当前对象”

this最常的用法:

  1.  在程序中产生二义性之处,应使用this来指明当前对象;普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。

public class User {
    int id;        //id
    String name;   //账户名
    String pwd;   //密码
 
    public User() {
    }
    public User(int id, String name) {
        System.out.println("正在初始化已经创建好的对象:"+this);
        this.id = id;   //不写this,无法区分局部变量id和成员变量id
        this.name = name;
    }
    public void login(){
        System.out.println(this.name+",要登录!");  //不写this效果一样
    }  
     
    public static void main(String[] args) {
        User  u3 = new User(101,"高小七");
        System.out.println("打印高小七对象:"+u3);
        u3.login();
    }
}

  2. 使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。

public class TestThis {
    int a, b, c;
 
    TestThis() {
        System.out.println("正要初始化一个Hello对象");
    }
    TestThis(int a, int b) {
        // TestThis(); //这样是无法调用构造方法的!
        this(); // 调用无参的构造方法,并且必须位于第一行!
        a = a;// 这里都是指的局部变量而不是成员变量
// 这样就区分了成员变量和局部变量. 这种情况占了this使用情况大多数!
        this.a = a;
        this.b = b;
    }
    TestThis(int a, int b, int c) {
        this(a, b); // 调用带参的构造方法,并且必须位于第一行!
        this.c = c;
    }
 
    void sing() {
    }
    void eat() {
        this.sing(); // 调用本类中的sing();
        System.out.println("你妈妈喊你回家吃饭!");
    }
 
    public static void main(String[] args) {
        TestThis hi = new TestThis(2, 3);
        hi.eat();
    }
}

  3. this不能用于static方法中。this指对象,不能用于类。

5、static

static修饰的成员变量和方法,从属于类。

普通变量和方法从属于对象。

在类中,用static声明的成员变量为静态成员变量,也称为类变量。 类变量的生命周期和类相同,在整个应用程序执行期间都有效。它有如下特点:

  1. 为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。

  2. 对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享!!

  3. 一般用“类名.类属性/方法”来调用。(也可以通过对象引用或类名(不需要实例化)访问静态成员。)

  4. 在static方法中不可直接访问非static的成员。(在static的方法中不可调用非static的方法!)

public class User2 {
    int id; // id
    String name; // 账户名
    String pwd; // 密码
     
    static String company = "北京尚学堂"; // 公司名称
     
     
    public User2(int id, String name) {
        this.id = id;
        this.name = name;
    }
     
    public void login() {
        printCompany();
        System.out.println(company); 
        System.out.println("登录:" + name);
    }
     
    public static void printCompany() {
//         login();//调用非静态成员,编译就会报错
        System.out.println(company);
    }
     
    public static void main(String[] args) {
        User2 u = new User2(101, "高小七");
        User2.printCompany();
        User2.company = "北京阿里爷爷";
        User2.printCompany();
        u.printCompany();//静态方法一般用"类名.类属性/方法"来调用!
        u.login();
    }
}

 

6、static初始化块???

构造方法用于对象的初始化!静态初始化块,用于类的初始化操作!在静态初始化块中不能直接访问非static成员。

注意事项:

  静态初始化块执行顺序(学完继承再看这里):

  1. 上溯到Object类,先执行Object的静态初始化块,再向下执行子类的静态初始化块,直到我们的类的静态初始化块为止。

  2. 构造方法执行顺序和上面顺序一样!!

public class User3 {
    int id;        //id
    String name;   //账户名
    String pwd;   //密码
    static String company; //公司名称
    static {
        System.out.println("执行类的初始化工作");
        company = "北京尚学堂";
        printCompany();
    }  
    public static void printCompany(){
        System.out.println(company);
    }  
    public static void main(String[] args) {
        User3  u3 = new User3();
    }
}

7、参数传值机制???

Java中,方法中所有参数都是“值传递”,也就是“传递的是值的副本”。 也就是说,我们得到的是“原参数的复印件,而不是原件”。因此,复印件改变不会影响原件。

· 基本数据类型参数的传值

  传递的是值的副本。 副本改变不会影响原件。

· 引用类型参数的传值

  传递的是值的副本。但是引用类型指的是“对象的地址”。因此,副本和原参数都指向了同一个“地址”,改变“副本指向地址对象的值,也意味着原参数指向对象的值也发生了改变”。

public class User4 {
    int id;        //id
    String name;   //账户名
    String pwd;   //密码
       
    public User4(int id, String name) {
        this.id = id;
        this.name = name;
    }
      
    public   void   testParameterTransfer01(User4  u){
        u.name="高小八";
    }
     
    public   void   testParameterTransfer02(User4  u){
        u  =  new  User4(200,"高三");
    }
      
    public static void main(String[] args) {
        User4   u1  =  new User4(100, "高小七");
         
        u1.testParameterTransfer01(u1); 
        System.out.println(u1.name);
 
        u1.testParameterTransfer02(u1);
        System.out.println(u1.name);
    }
}

8、包

 包机制是Java中管理类的重要手段。 开发中,我们会遇到大量同名的类,通过包我们很容易对解决类重名的问题,也可以实现对类的有效管理。 包对于类,相当于文件夹对于文件的作用。

通过package实现对类的管理,package的使用有两个要点:

1. 通常是类的第一句非注释性语句。

2. 包名:域名倒着写即可,再加上模块名,便于内部管理类。

五、面向对象进阶

继承、封装、多态

1、继承

extends 扩展

package com.stu;

public class TestExtends {
	public static void main(String[] args) {
		Stu s1 = new Stu("小明",18,"计算机");
		s1.study();
		// instanceof 二元运算符 :左边是对象,右边是类;
		//当对象是右面类或子类所创建对象时,返回true;否则,返回false。
		System.out.println(s1 instanceof Person);
        System.out.println(s1 instanceof Stu);	
	}
}

class Person {
	int id;
	String name;
	int age;
	
	public void eat() {
		System.out.println(name+"吃饭!");
	}
}

class Stu extends Person {
	String major;
	
	public Stu(String name, int age, String major){
		this.name = name;
		this.age = age;
		this.major = major;
	}
	
	public void study() {
		System.out.println(name+major+"学习java!");
	}	
}
public class Testoverride {
	public static void main(String[] args) {
		Vehicle v = new Vehicle();
		Horse h = new Horse();
		Plane p = new Plane();
		v.run();
		v.stop();
		h.run();
		h.stop();
		p.run();
		p.stop();
	}
}

class Vehicle {
	public void run() {
		System.out.println("跑……");
	}
	
	public void stop() {
		System.out.println("停……");
	}
}

class Horse extends Vehicle {
	public void run() { //重写父类方法
		System.out.println("四蹄翻飞,嘚嘚嘚……");
	}
}

class Plane extends Vehicle {
	public void run() { //重写父类方法
		System.out.println("天上飞……");
	}
	public void stop() { //重写父类方法
		System.out.println("坠毁了……");
	}
}

2、封装

需要让用户知道的才暴露出来,不需要让用户知道的全部隐藏起来,这就是封装。说的专业一点,封装就是把对象的属性和操作结合为一个独立的整体,并尽可能隐藏对象的内部实现细节

  Java是使用“访问控制符”来控制哪些细节需要封装,哪些细节需要暴露的。 Java中4种“访问控制符”分别为private、default、protected、public,它们说明了面向对象的封装性,所以我们要利用它们尽可能的让访问权限降到最低,从而提高安全性。

3、多态

父类的很多子类有同一方法,但是行为不同。比如动物类,其中狗叫是旺旺,猫叫是喵喵。

class Animal {
    public void shout() {
        System.out.println("叫了一声!");
    }
}
class Dog extends Animal {
    public void shout() {
        System.out.println("旺旺旺!");
    }
    public void seeDoor() {
        System.out.println("看门中....");
    }
}
class Cat extends Animal {
    public void shout() {
        System.out.println("喵喵喵喵!");
    }
}
public class TestPolym {
    public static void main(String[] args) {
        Animal a1 = new Cat(); // 向上可以自动转型
        //传的具体是哪一个类就调用哪一个类的方法。大大提高了程序的可扩展性。
        animalCry(a1);
        Animal a2 = new Dog();
        animalCry(a2);//a2为编译类型,Dog对象才是运行时类型。
         
        //编写程序时,如果想调用运行时类型的方法,只能进行强制类型转换。
        // 否则通不过编译器的检查。
        Dog dog = (Dog)a2;//向下需要强制类型转换
        dog.seeDoor();
    }
 
    // 有了多态,只需要让增加的这个类继承Animal类就可以了。
    static void animalCry(Animal a) {
        a.shout();
    }
 
    /* 如果没有多态,我们这里需要写很多重载的方法。
     * 每增加一种动物,就需要重载一种动物的喊叫方法。非常麻烦。
    static void animalCry(Dog d) {
        d.shout();
    }
    static void animalCry(Cat c) {
        c.shout();
    }*/
}
package com.test;

public class TestMusic {
	public static void main(String[] args) {
		Musician m = new Musician();
		Instrument i = new Instrument();
		Instrument e = new Erhu();//多态
		Instrument p = new Piano();
		Instrument v = new Violin();
		m.play(i);
		m.play(e);
		m.play(p);
		m.play(v);
	}
}

//乐手类
class Musician {
	
	public void play(Instrument i) {// 父类引用做方法的形参,子类做实参
		i.makeSound();
	}
}

//乐器类
class Instrument {
	public void makeSound() {
		System.out.println("乐器的声音……");
	}
}

//二胡,乐器的子类
class Erhu extends Instrument{
	@Override //父类的方法重写,此标志可写可不写.写上有注解并自动检查的好处
	//子类必须实现父类的抽象方法,否则编译错误
	public void makeSound() {
		System.out.println("二胡的声音……");
	}
}

//钢琴,乐器的子类
class Piano extends Instrument{
	@Override
	public void makeSound() {
		System.out.println("钢琴的声音……");
	}
}

//小提琴,乐器的子类
class Violin extends Instrument{
	@Override
	public void makeSound() {
		System.out.println("小提琴的声音……");
	}
}

 展示了多态最为多见的一种用法,即父类引用做方法的形参,实参可以是任意的子类对象,可以通过不同的子类对象实现不同的行为方式。

4、抽象

抽象方法:abstract修饰的方法,只有声明,没有方法体。含有抽象方法的类必须被声明为抽象类抽象类的子类必须覆写所有的抽象方法才能被实例化,否则这个子类还是个抽象类。

子类必须要给抽象方法具体的实现。

抽象类:包含抽象方法的类就是抽象类。

//抽象类
abstract class Animal {
    abstract public void shout();  //抽象方法
}
class Dog extends Animal { 
    //子类必须实现父类的抽象方法,否则编译错误
    public void shout() {
        System.out.println("汪汪汪!");
    }
    public void seeDoor(){
        System.out.println("看门中....");
    }
}
//测试抽象类
public class TestAbstractClass {
    public static void main(String[] args) {
        Dog a = new Dog();
        a.shout();
        a.seeDoor();
    }
}

5、接口

接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。

public class TestInterface {
	public static void main(String[] args) {
		Volant v1 = new Angel();
		Honest h1 = new Angel();
		Honest h2 = new GoodMan();
		v1.fly();
		System.out.println("天使的飞行高度:"+v1.fly_hight);
		h1.helpOther();
		h2.helpOther();
	}
}
 // 飞行接口
interface Volant {
	int fly_hight = 100;
	void fly();
}

// 善良接口
interface Honest {
	void helpOther();
}

class Angel implements Volant, Honest {
	public void fly() {
		System.out.println("我会飞");
	}
	public void helpOther() {
		System.out.println("帮助别人飞");
	}
}

class GoodMan implements Honest{
	public void helpOther() {
		System.out.println("帮助别人过马路");
	}
	
}

 接口完全支持多继承。和类的继承类似,子接口扩展某个父接口,将会获得父接口中所定义的一切。

interface A {
    void testa();
}
interface B {
    void testb();
}
/**接口可以多继承:接口C继承接口A和B*/
interface C extends A, B {
    void testc();
}
public class Test implements C {
    public void testc() {
    }
    public void testa() {
    }
    public void testb() {
    }
}

 面向接口编程

 接口就是规范,就是项目中最稳定的东东! 面向接口编程可以让我们把握住真正核心的东西,使实现复杂多变的需求成为可能。

通过面向接口编程,而不是面向实现类编程,可以大大降低程序模块间的耦合性,提高整个系统的可扩展性和和可维护性。

6、内部类???

把一个类放在别的一个类内部定义,称为内部类

内部类可以直接访问外部类的属性,外部类无法找到内部类声明的属性。

Java中内部类主要分为成员内部类(非静态内部类、静态内部类)、匿名内部类、局部内部类

还有一种内部类,它是定义在方法内部的,作用域只限于本方法,称为局部内部类

7、String类和常量池

public class TestFile1{
	public static void main(String args[]) {
	    String s = "abc";
	    String ss = "abc";
	    String s3 = "abc" + "def";
	    String s4 = "abcdef";
	    String s5 = ss + "def";
	    String s6 = new String("abc");
	    System.out.println(s == ss); //true
	    System.out.println(s3 == s4);//true
	    System.out.println(s4 == s5);//false
	    System.out.println(s4.equals(s5));//true
	    System.out.println(s.equals(s6));//true
	    System.out.println(s == s6);//false
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值