欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > > 文章正文

java基础,

来源: javaer 分享于  点击 5206 次 点评:251

java基础,


1 .  关于equals()方法和hashcode()方法

相同的对象一定具有相同的hashcode(),不同的对象也有可能具有相同的hashcode(),产生hash碰撞

重载equals的时候,一定要(正确)重载hashCode  
  使得equals成立的时候,hashCode相等,也就是a.equals(b)->a.hashCode()   ==   b.hashCode(),或者说此时,

equals是hashCode相等的充分条件,hashCode相等是equals的必要条件(从数学课上我们知道它的逆否命题:

hashCode不相等也不会equals),但是它的逆命题,hashCode相等一定equals以及否命题不equals时

hashCode不等都不成立。  
   
  所以,如果面试的时候,最好把hashCode与equals之间没有强制关系,以及根据(没有语法约束力的)规范的角度,

应当做到...这两层意思都说出来:

 总结一下,equals()是对象相等性比较,hashCode()是计算对象的散列值,当然他们的依据是对象的属性。

 对于equals,一般我们认为两个对象同类型并且所有属性相等的时候才是相等的,在类中必须改写equals,

因为Object类中的equals只是判断两个引用变量是否引用同一对象,如果不是引用同一对象,

即使两个对象的内容完全相同,也会返回false。当然,在类中改写这个equals时,你也可以只对部分属性进行比较,

只要这些属性相同就认为对象是相等的。  
   
  对于hashCode,只要是用在和哈希运算有关的地方和equals一样,在你的类中也应该改写。

当然如果两个对象是完全相同的,那么他们的hashCode当然也是一样的,但是像前面所述,规则可以由你自己来定义,

因此两者之间并没有什么必然的联系。  
   

  当然,大多数情况下我们还是根据所有的属性来计算hashCode和进行相等性比较。

hashcode()方法将对象的内存地址进行hash运算,返回的是一个int型的hash值

 

2. static关键字

static关键字修饰成员变量,称为静态变量。静态变量被所有实例共享,可以使用类名.变量名访问

static关键字只能修饰成员变量,不能修饰局部变量

static修饰方法块,不用创建对象直接通过类名.方法名的方式来访问

package com.base.door;

public class Example {
	static {
		System.out.println("测试类的代码执行了");
	}

	public static void main(String[] args) {
		Person p1 = new Person();
		Person p2 = new Person();

	}

}

class Person {
	static String country;

	static {
		country = "china";
		System.out.println("Person类中的静态代码被执行了");
	}
}

虚拟机首先会加载类Example,在加载累的同时就会执行该类的静态代码块,紧接着调用main()方法,在该方法中创建两个Person对象,但是两次实例化的过程中,静态代码块只会执行一次。

 

 

 

什么是单例模式?

1. 构造方法私有化
2. 静态属性指向实例
3. public static的 getInstance方法,返回第二步的静态属性

3. 多态 父类变量引用不同的子类对象,多态解决方法同名问题,允许使用一个父类类型的变量来引用一个子类类型的对象,根据被引用子类的

不同,得到不同的运行结果

package com.base.door;
//定义接口Animal
interface Animal {
	void shout();
}
//定义Cat泪腺Animal接口
class Cat implements Animal {
	public void shout() {
		System.out.println("喵喵......");
	}
}
class Dog implements Animal{
	public void shout(){
		System.out.println("汪汪....");
	}
}

public class Example02 {

	public static void main(String[] args) {
		
		Animal an1 = new Cat();
		Animal an2 = new Dog();
		animalShout(an1);
		animalShout(an2);
	}
//定义静态方法animalShout接受一个animal类型的输入

	private static void animalShout(Animal an) {
		an.shout();
		
	}

}

但是不能通过父类变量调用子类的某些方法

package com.base.door;
//定义animal接口
interface Animal {
	void shout();
}
//定义cat类实现animal接口
class Cat implements Animal {
	public void shout() {
		System.out.println("喵喵......");
	}
	void sleep(){
		System.out.println("猫睡觉");
	}
}

public class Example02 {

	public static void main(String[] args) {
		
		Cat cat = new Cat(); 
	
		animalShout(cat);//调用animalShout()方法,cat作为参数传入
	
	}

	private static void animalShout(Animal animal) {
		animal.shout();
		animal.sleep();
		
	}

}

animalShout()方法调用时传入了Cat类型的对象,而方法的参数类型为Animal类型,这便将Cat对象当作父类Animal类型使用,当编译器检测到

animal.sleep()时,发现Animal类没有定义sleep()方法,从而报错

这时我们在animalShout()方法中进行强转

private static void animalShout(Animal animal) {
		Cat cat = (Cat) animal;
		cat.shout();
		cat.sleep();
		
	}

但是强转可能出现类型错误,如Animal类型无法转化为Cat类型,像这样

package com.base.door;
//定义animal接口
interface Animal {
	void shout();
}
//定义cat类实现animal接口
class Cat implements Animal {
	public void shout() {
		System.out.println("喵喵......");
	}
	void sleep(){
		System.out.println("猫睡觉");
	}
}
class Dog implements Animal {
	public void shout() {
		System.out.println("汪汪......");
	}
	
}

public class Example02 {

	public static void main(String[] args) {
		
		Dog dog = new Dog(); 
	
		animalShout(dog);//调用animalShout()方法,cat作为参数传入
	
	}
	//定义静态方法animalShout(),接受一个Animal类型的参数
	private static void animalShout(Animal animal) {
		Cat cat = (Cat) animal;
		cat.shout();
		cat.sleep();
		
	}

}
//针对这种情况,java提供instanceod,判断一个对象是否为某个类(或者接口的实例或者子类实例)

对象(或者对象的引用变量) instanceod 类(或接口) 像这样

package com.base.door;
//定义animal接口
interface Animal {
	void shout();
}
//定义cat类实现animal接口
class Cat implements Animal {
	public void shout() {
		System.out.println("喵喵......");
	}
	void sleep(){
		System.out.println("猫睡觉");
	}
}
class Dog implements Animal {
	public void shout() {
		System.out.println("汪汪......");
	}
	
}

public class Example02 {

	public static void main(String[] args) {
		
		Dog dog = new Dog(); 
	
		animalShout(dog);//调用animalShout()方法,cat作为参数传入
	
	}
	//定义静态方法animalShout(),接受一个Animal类型的参数
	public static void animalShout(Animal animal) {
		if(animal instanceof Cat){
		Cat cat = (Cat) animal;
		cat.shout();
		cat.sleep();
		
	}else{
		System.out.println("this animal is not a cat");
	}

}
}

由于传入的是Dog类型,所以打印

this animal is not a cat

 

4.关于String和StringBuffer类

4.1String类表示的字符串是常量,一旦创建后,内容和长度都是无法改变的。而StringBuffer表示字符容器,其内容和长度都可以修改。

在操作字符串时,如果该字符串仅用于表示数据类型,则使用String类即可,但是如果需要对字符串中的字符进行增删操作,

则使用StringBuffer类

4.2String覆盖Object类下的equals()方法,而StringBuffer类没有覆盖Object类的equals()方法

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1.equals(s2));
StringBuffer sb1 = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(sb1.equals(sb2));
		

结果分别是

 

 

4.3 String类对象可以用操作符+进行连接,而StringBuffer对象不能,具体示例如下

5. jdk7新特性 switch语句支持字符串类型

	String week = "Friday";
		switch (week) {
		case "Monday":
			System.out.println("今天是星期一");
			break;
		case "Friday": {
			System.out.println("今天星期五");
		}

 

6. 装饰者模式

package com.base.door;

class Car {
	private String carName;

	public Car(String carName) {
		this.carName = carName;
	}

	public void show() {
		System.out.println("我是" + carName + ",具有基本功能");
	}

}

class RadarCar {

	public Car myCar;

	public RadarCar(Car myCar) {
		this.myCar = myCar;
	}

	public void show() {
		myCar.show();
		System.out.println("具有倒车雷达功能");
	}
}

public class Example06 {

	public static void main(String[] args) {
		Car benz = new Car("benz");
		System.out.println("---------------包装前--------------");
		benz.show();
		RadarCar decoratedCar_benz = new RadarCar(benz);
		System.out.println("---------------包装后--------------");
		decoratedCar_benz.show();

	}

}

当RadarCar对象调用收方法时,RaderCar包装后的对象不仅具有车的基本功能,也具有倒车雷达的功能

6.static关键字 只需将static关键字放在定义之前,就可以将字段或方法设定为static,例如下面的代码就生成了一个static字段,并对其进行了

初始化

class StaticTest {
	static int i = 47;
}

现在即使你创建两StaticTest对象,StaticTest.i也只有一份存储空间,这两个对象共享一个i,下面的代码st1.i和st2.i指向同一存储空间

class StaticTest {
	static int i = 47;
}

public class Test {

	public static void main(String[] args) {
		StaticTest st1 = new StaticTest();
		StaticTest st2 = new StaticTest();
		System.out.println(st1.i==st2.i);
	}

	}

 
这里既可以通过一个对象去定位它,st2.i,也可以通过类型将以引用,StaticTest.i++
static修饰方法和修饰变量相似
	

7.java编码风格

在java编程语言编码规定中,代码风格是这样的:类的首字母要大写;如果类名由几个单词组成,那么把他们并在一起(也就是说,不需要用

下划线分割名字),其中的每个内部单词都采用大些形式,如

class AllTheClolrOfTheRainboe{
		
	}

这种风格有时候被称作驼峰风格。几乎所有的内容方法、字段以及对象引用名称等,公认的风格与类的风格一样,只是标识符的

第一个字母才用小写。详情参考阿里巴巴java规范手册

8 equals 方法和==比较,在object类,equals方法与==没有差别,重写的话看实现,==号在基本数据类型相当于比较数值是否相等,在对象比较时比较对象的地址。

看下列实例

public class Test {

	public static void main(String[] args) {
		Integer n1 = new Integer(47);
		Integer n2 = new Integer(47);
		System.out.println(n1 == n2);
		System.out.println(n1 != n2);
	}

	}	

比较对象的引用


 
比较对象的实际内容一般使用.equals()方法,由于integer类重写了.equals方法,返回true	
public class Test {

	public static void main(String[] args) {
	Integer n1 = new Integer(47);
	Integer n2 = new Integer(47);
	System.out.println(n1.equals(n2));
	}
	}

equals方法中默认比较的是引用,除非在新类中重写.equals()方法

class Value {
	int i;
}

public class Test {

	public static void main(String[] args) {
	Value n1 = new Value();
	Value n2 = new Value();
	n1.i = n2.i = 100;
	System.out.println(n1.equals(n2));
	}
}

由于未重写.equals方法,默认比较引用,引用不同,返回false

9.对象可能不被垃圾回收

垃圾回收并不等于析构

垃圾回收只与内存有关

 

10.

有如下一段程序:

1

2

3

4

5

6

7

8

9

10

11

12

13

public class Test{

    private static int i=1;

    public int getNext(){

         return i++;

    }

    public static void main(String [] args){

        Test test=new Test();

        Test testObject=new Test();

        test.getNext();

        testObject.getNext();

        System.out.println(testObject.getNext());

    }

}

请问最后打印出来的是什么?()

正确答案: B   你的答案: B (正确)

2
3
4
5

解析

return i++, 先返回i,然后i+1;

第一次调用getNext()方法时,返回的是1,但此时i=2;

第二次调用 getNext()方法时,返回的是2,但此时i=3;

第三次调用 getNext()方法时,返回的是3,但此时i=4;

先返回,后自增改为++i先自增,后返回,结果4
 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关文章

    暂无相关文章

用户点评