小言_互联网的博客

JavaSE Day08

386人阅读  评论(0)

对象类型转换 (Casting )

基本数据类型的Casting:

  • 自动类型转换:小的数据类型可以自动转换成大的数据类型。
    如long g=20; double d=12.0f
  • 强制类型转换:可以把大的数据类型强制转换(casting)成小的数据类型
    如 float f=(float)12.0d; int a=(int)1200L
  • 对Java对象的强制类型转换称为造型
    从子类到父类的类型转换可以自动进行
    从父类到子类的类型转换必须通过造型(强制类型转换)实现
    无继承关系的引用类型间的转换是非法的

举例1

//自动类型转换
Student s = new Student();
Person p = s;

Object obj = "hello";//String是引用类型,String类型自动转换成Object类型
String s = (String) Obj;
//强制类型转换
Person p = new Person();
Syudent s = (Student) p;

举例2

public class Test{ 
	   public void method(Person e) {	 //设Person类中没有getschool()方法
		 // System.out.pritnln(e.getschool());   //非法,编译时错误
		     if(e  instanceof  Student){
		          Student me = (Student)e;	//将e强制转换为Student类型
		          System.out.pritnln(me.getschool());
		     }	    
        }

       public static  void main(Stirng args[]){
	         Test t = new Test();
	         Student m = new Student();
	         t.method(m);
	   }
}


图解

==操作符与equals()方法

==操作符

  • 基本类型比较值:只要两个变量的值相等,即为true.
    int a=5;
    System.out.println(a == 6) ; //false
  • 引用类型比较引用(是否指向同一个对象):只有指向同一个对象时(堆内存地址相同),= = 才返回true。
    Person p1=new Person();
    Person p2=new Person();
    System.out.println(p1 == p2) ; //false
  • 用“= =”进行比较时,符号两边的数据类型必须兼容(可自动转换的基本数据类型除外),否则编译出错;
    兼容指:数据兼容是指,相比较的两者必须为同一类型或可以自动转换的类型(如int与long、子类与父类等),两个不同类的对象之间无法用“= =”比较。

equals()方法

  • equals():所有类都继承了Object,也就获得了equals()方法,并且可以重写。
  • 只能比较引用类型,其作用与“==”相同,比较是否指向同一个对象。
    格式:obj1.equals(obj2);
  • 特例:当用equals()方法进行比较时,对类File、String、Date及包装类(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个对象;
    原因:在这些类中重写了Object类的equals()方法。
  • 相比较的两者必须为同一类型或可以自动转换的类型(如int与long、子类与父类等),两个不同类的对象之间无法用“= =”比较。
  • 注意:
    在一般情况下,”= =”与”equals()”比较的是p和q是否指向同一个对象,即使p和q指向的对象的内容相同,但不是同一个对象,也返回false;equals()在上述几种特殊情况下比较的是p和q所指向的对象的类型和内容。也就是”==”在任何情况下比较的都是内存地址,equals()分情况。

String对象的创建

举例

String s1 = "123";
String s2 = "123";
System.out.println(s1 == s2);//true
String s3 = new String("123");
String s4 = new String("123");
System.out.println(s3 == s4);//false

new一定开辟两块堆内存空间,不管对象的内容是否相同,因此s3和s4是内容相同的不同引用(堆地址不同);不使用new时,当对象的内容相同时,系统不再分配新的空间,而是将已有的空间地址赋给新引用,因此s1和s2指向相同的内存空间(是同一内存空间的不同引用)。

  • 字面量赋值String对象时,只在常量池创建一个对象。

练习

  1. 代码如下:
int it = 65;
float fl = 65.0f;
System.out.println(6565.0f是否相等?” + (it == fl)); //true

char ch1 = 'A'; char ch2 = 12;
System.out.println("65和'A'是否相等?" + (it == ch1));//true
System.out.println(12和ch2是否相等?" + (12 == ch2));//true

String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("str1和str2是否相等?"+ (str1 == str2));//false

System.out.println("str1是否equals str2?"+(str1.equals(str2)));//true

System.out.println(“hello” == new java.sql.Date()); //编译不通过
Person p1 = new Person();
p1.name = "atguigu";//字面量赋值

Person p2 = new Person();
p2.name = "atguigu";//字面量赋值

System.out.println(p1.name .equals( p2.name));//true,比较内容
System.out.println(p1.name == p2.name);//true,字面量赋值,内容相同,地址相同
System.out.println(p1.name == "atguigu");//true,字面量赋值,内容相同,地址相同

String s1 = new String("bcde");
String s2 = new String("bcde");
System.out.println(s1==s2);//false,s1和s2new创建,不管内容是否相同,总是开辟两块不同的内存空间
  1. 编写Order类,有int型的orderoId,String型的ordername,相应的getter()和setter()方法,两个参数的构造器,重写父类的equals()方法:public boolean equals(Object obj),并判断测试类中创建的两个对象是否相等。
package practice1.test;

public class Order {
	int orderold;
	String ordername;
	
	public Order(int orderold, String ordername) {
		this.orderold = orderold;
		this.ordername = ordername;
	}
	
	@Override
	public boolean equals(Object obj) {
		boolean flag = false;
		Order ord = (Order)obj;
		if(this.orderold == ord.orderold && this.ordername.equals(ord.ordername)) {
			flag = true;
		}
		return flag;
	}
	
}
package practice1.test;

public class Test {
	public static void main(String[] args) {

		Order ord1 = new Order(22, "XiaoMing");
		Order ord2 = new Order(23, "LiMing");
		System.out.println(ord1.equals(ord2));
		
	}
}
  1. 请根据以下代码自行定义能满足需要的MyDate类,在MyDate类中覆盖equals方法,使其判断当两个MyDate类型对象的年月日都相同时,结果为true,否则为false。 public boolean equals(Object obj)
package practice1.test;

public class MyData {
	int year;
	int month;
	int day;
	
	public MyData(int year, int month, int day) {
		this.year = year;
		this.month = month;
		this.day = day;
	}
	
	@Override
	public boolean equals(Object obj) {
		boolean flag = false;
		MyData md = (MyData)obj;
		if(this.year == md.year && this.month == md.month && this.day == md.day) {
			flag = true;
			System.out.println("年月日均相同");
		}
		if(this.year != md.year ) {
			System.out.println("年份不相同");
		}
		if(this.month != md.month) {
			System.out.println("月份不相同");
		}
		if(this.day != md.day) {
			System.out.println("日期不相同");
		}
		return flag;
	}
	
}
package practice1.test;

public class Test {
	public static void main(String[] args) {

		MyData md1 = new MyData(2019, 9, 10);
		MyData md2 = new MyData(2019, 9, 10);
		System.out.println(md1.equals(md2));
		
		MyData md3 = new MyData(2019, 9, 10);
		MyData md4 = new MyData(2020, 9, 10);
		System.out.println(md3.equals(md4));
		
	}
}
  1. 判断字符串是否是一个空字符串。
package practice1.test;

public class StringIsEmpty {
	
	public static boolean isEmpty(String str) {
		boolean flag = false;
		if(str != null && str.equals("")) {
			flag = true;
		}
		return flag;
	}
	
	public static void main(String[] args) {
		String s = "";
		System.out.println(s.isEmpty());//String类自带的isEmpty方法,true
		System.out.println(StringIsEmpty.isEmpty(s));//true
	}
	
}

toString()方法

toString()方法在Object类中定义,其返回值是String类型,返回类名和它的堆内存地址。

Person p = new Student();
System.out.println(p.toString());

输出:practice1.test.Student@27973e9b

包装类(Wrapper)

  • 针对八种基本定义相应的引用类型—包装类(封装类)
  • 有了类的特点,就可以调用类中的方法。

八种类型的包装类

基本数据类型 包装类
boolean Boolean
byte Byte
short Short
int Integer
long Long
char Character
float Float
double Double

装箱和拆箱

概念

1. 装箱

  • 基本数据类型包装成包装类的实例。
  • 自动装箱:
    int i = 5;
    Integer t = i;

    Integer m = 20;

2. 拆箱

  • 获得包装类对象中包装的基本类型变量。
  • 调用包装类的 变量名.xxxValue() 方法:
    float f = fl.floatValue();
  • 自动拆箱:
    float f = fl;

基本数据类型与字符串之间的转换

1. 字符串转换成基本数据类型

  • 通过包装类.parseXxx(String s) 静态方法:
    Integer i = Integer.parseInt (“20”);—自动装箱到Integer
    (等于int i = Integer.parseInt(“20”);—自动拆箱到int )

2. 基本数据类型转换成字符串

  • 调用字符串重载的valueOf()方法:
    String fstr = String.valueOf(2.34f);
  • 更直接的方式:
    String intStr = 5 + ""

3.包装类的用法举例

  • 装箱:包装类使得一个基本数据类型的数据变成了类。有了类的特点,可以调用类中的方法。
  • 拆箱:将数字包装类中内容变为基本数据类型。
  • 包装类在实际开发中用的最多的在于字符串变为基本数据类型。
String str1 = "18" ;
String str2 = "21.2" ;	
int x = Integer.parseInt(str1);	// 将字符串变为int型,也可写成Integer x = Integer.parseInt(str1);
float f = Float.parseFloat(str2) ; // 将字符串变为float型

static关键字

情景

考虑如下情况,所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。此时需要定义一个可供所有对象共用的属性。

  • 创建两个Circle对象
    Circle c1=new Circle(2.0); //c1.radius=2.0
    Circle c2=new Circle(3.0); //c2.radius=3.0

    c1的radius独立于c2的radius,存储在不同的空间。c1中的radius变化不会影响c2的radius。

类属性、类方法

1. 类属性

  • 类属性(类变量、静态变量)是指在各个对象之间共享的变量。在设计类时,分析哪些属性不因对象的不同而改变,将这些属性设置为类属性。相应的方法设置为类方法。
  • 访问方式:类名.属性

2. 类方法

  • 如果方法与调用者无关,则这样的方法通常被声明为类方法,由于类方法不需要创建对象就可以调用,从而简化了方法的调用。
  • 调用方法:类名.方法()

3. 注意

  • 一般static修饰的属性和方法只用public修饰。

static关键字

1. 使用范围:
在Java类中,可用static修饰属性、方法、代码块、内部类,只要是static修饰的,就是共用的,全局唯一。

2. 被修饰后的成员具备以下特点:

  • 随着类的加载而加载;
  • 优先于对象存在;
  • 修饰的成员,被所有对象所共享(类属性);
  • 访问权限允许时,可不创建对象,直接被类调用(类方法)。
public class Student{
	String name;//实例变量
	int age;//实例变量
	static int school;//类变量
}

实例变量:只有在对象实例化之后才可使用;
类变量:不需要实例化对象,可以直接通过类名.属性访问。

类方法

  • 没有对象的实例时,可以用 类名.方法名() 的形式访问由static标记的类方法。
  • 在static方法内部只能访问类的static属性,不能访问类的非static属性。
  • 因为不需要实例就可以访问static方法,因此static方法内部不能有this,也不能有super。
  • 重载的方法需要同时为static的或者非static的。
  • 因为不需要实例化对象就可以调用类方法,因此类方法用于开发工具类比较多
class Person {
       private int id;
       private static int total = 0;
       
       public static int getTotalPerson() { 
	   id++;	
	   return total;
       }
       
       public Person() {
         	total++;
 	        id = total;
       }
}

public class TestPerson {
        public static void main(String[] args) {
 	    System.out.println("Number of total is " + Person.getTotalPerson());
 	    //一开始没有创建对象,故不调用构造方法,total为0,id为0
	    //没有创建对象也可以访问静态方法
 	    Person p1 = new Person();
 	    //创建新对象,调用构造方法,total自增变为1,id赋值为1,调用getTotalPerson()方法后,id自增1变为2,total不变为1
     	System.out.println( "Number of total is "+ Person.getTotalPerson());
        }
}

结果:
Number of total is 0
Number of total is 1

单例 (Singleton)设计模式

概念

  • 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。

  • 单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。

实现方法

  • 将类的构造方法的访问权限设置为private —— 不能用new操作符在类的外部产生类的对象,保证类在一个虚拟机中只能产生一个对象。
  • 在类内部产生该类的对象
  • 使用某个静态方法来返回类内部创建的对象 —— 不能new对象,无法创建该类的对象,因此不能访问类内方法,设置成static方法就可以使用类名来调用类内方法了。
  • 接收实例对象的引用必须定义成静态的 —— 静态方法只能访问类中的静态成员变量。

使用场景

实例化对象耗费大量的时间和资源。实例化对象之后,调用equals()方法返回的均为true。

public class TestSingle{
	public static void main(String args[]) {		
		Single  s1 = Single.getSingle();      //访问静态方法
		Single  s2 = Single.getSingle();
		if (s1==s2){
			System.out.println("s1 is equals to s2!");//true
		}
	}
}

代码实现

饿汉式

  • 类内创建一个对象,只要有人调用静态方法,就返回同一个对象。
package practice1.test;

public class SingletonHungry {
	
	private SingletonHungry() {}//构造方法私有化,外部不能使用new实例化对象
	
	private static SingletonHungry single = new SingletonHungry();
	
	public static SingletonHungry getNewInstance() {
		return single;
	}
		
}
package practice1.test;

public class Test {
	public static void main(String[] args) {
	SingletonHungry single = SingletonHungry.getNewInstance();	
}

懒汉式

  • 最开始类内部不创建对象,为null,当有人实例化第一个对象之后,以后再调用静态方法返回的都是第一个人创建的对象。
package practice1.test;

public class SingletonLazy {
	
	private SingletonLazy() {}//构造方法私有化,外部不能使用new实例化对象
	
	private static SingletonLazy single = null;
	
	public static SingletonLazy getNewInstance() {
		if(single == null) {
			single = new SingletonLazy();
		}
		return single;
	}
	
}
package practice1.test;

public class Test {
	public static void main(String[] args) {
	SingletonLazy single = SingletonLazy.getNewInstance();	
}

main方法

由于java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,又因为java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static的,该方法接收一个String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数。


转载:https://blog.csdn.net/lemon6564562/article/details/105443416
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场