1.引用类型变量
Java语言有了垃圾回收机制,就不需要开发人员去控制内存回收,简单点来说就是当一个变量没有被引用指向时,垃圾回收机制就会回收(Java虚拟机的具体章节会在后面Java基础篇之Java虚拟机)
基本类型的值就是数值,字符,或者布尔值;
int a = 1;
分配a内存的同时,并存储a的值
引用类型的值是对象的引用,也就是对象内存里面的地址,通过引用里面存的对象地址去操作对象
T t = new T();
T t :开辟引用空间
new T() : 开辟数据空间
T t = new T() :赋值操作
引用类型变量的声明和使用总结
(1)把类名当作是一种类型来声明变量,这种变量叫引用类型变量。
如:People people;
(2)引用类型变量保存对象的“引用”,即对象的地址。
(3)对象的创建 new 类名() 如:new People();
(4)new创建对象后返回对象的引用,对象没有名字,只能使用对象的引用间接使用对象,引用类型变量就是专门用来保存对象引用的。
如:People people = new People();
(5)成员变量的默认值:数据型成员变量默认值为0,boolean型成员变量默认值为false,引用类型成员变量默认值为null。
(6)对象内存分配,对象是被保存在堆中的,对象没有名字。
对象中保存的是对象的成员变量。没有引用类型变量保存对象的引用时,对象被认为是垃圾,会被垃圾回收机制销毁。
(7)使用对象的引用来访问对象的成员变量与成员方法,都是使用“.”。
成员变量与成员方法统称为成员。
创建对象后直接访问成员,随之对象就会被销毁,这种对象称之为匿名对象。如:new People().name = "老王";
创建对象后返回的引用被引用类型变量保存,使用“引用类型变量.成员”;如:People p1 = new People(); p1.name = "老王";
2.值传递&引用传递
Java语言到底是值传递还是引用传递?这个网上有很多说法,那么就先理解什么是值传递引用传递是什么意思然后就会比较容易理解Java到底是值传递还是引用传递?
值传递:
调用方法时候,将值复制给形参一份,然后方法中对于形参的操作不会影响到实参的值。
引用传递:
调用方法时将地址传给形参,方法执行过程会影响实际值。
@org.junit.Test public void test3(){ Integer a = 3; Integer b = 4; String str1 = "aaaa"; String str2 = "bbbb"; Empolyee empolyee1 = new Empolyee(); empolyee1.setName("111"); change4(a,b,empolyee1,str1,str2); System.out.println("a:"+a+"----b:"+b+"----empolyee1:"+empolyee1.getName()+"----str1:"+str1+"----str2:"+str2); } public void change4(Integer a , Integer b ,Empolyee empolyee,String str1 ,String str2 ){ a = 5; b = 6; empolyee.setName("222"); str1 = "cccc"; str2 = "dddd"; }
输出结果:
a:3----b:4----empolyee1:222----str1:aaaa----str2:bbbb基本数据类型传值,对形参的修改不会影响实参;
引用类型传对象引用的地址副本,形参和实参指向同一个内存地址(同一个对象),所以对参数的修改会影响到实际的对象。
String, Integer, Double等immutable的类型特殊处理,可以理解为传值,最后的操作不会修改实参对象。
但是在Java语言中调用方法无论是传递给形参的是基本数据类型的【值拷贝】还是引用类型的【地址拷贝】,都是一种值的形式,所以才会有Java语言都是值传递的说法。
3.Object方法
public native int hashCode()public boolean equals(Object obj)protected native Object clone() throws CloneNotSupportedExceptionpublic String toString()public final native Class<?> getClass()protected void finalize() throws Throwable {}public final native void notify()public final native void notifyAll()public final native void wait(long timeout) throws InterruptedExceptionpublic final void wait(long timeout, int nanos) throws InterruptedExceptionpublic final void wait() throws InterruptedException1,equals()
equals()与"=="的区别:
Java基本类型而言:"=="就是比较两个值是否相等,没有用到equals()
包装类型而言,"=="是判断两个引用对象是否同一个,equals()则比较对象是否相等
2,hashCode()
hashCode() 返回散列值,而 equals() 是用来判断两个对象是否等价。等价的两个对象散列值一定相同,但是散列值相同的两个对象不一定等价。
3,toString()
/*自定义的Empolyee类*/Empolyee empolyee1 = new Empolyee();System.out.println(empolyee1.toString());//Empolyee@677327b6输出结果:默认显示的@后面是16进制散列码
注意:equals()方法和hashCode()方法同时重写
4.反射
Java反射说的是在运行状态中,对于任何一个类,我们都能够知道这个类有哪些方法和属性。对于任何一个对象,我们都能够对它的方法和属性进行调用。把这种动态获取对象信息和调用对象方法的功能称之为反射机制。
反射的优点:
可扩展性 :应用程序可以利用全限定名创建可扩展对象的实例,来使用来自外部的用户自定义类。
类浏览器和可视化开发环境 :一个类浏览器需要可以枚举类的成员。可视化开发环境(如 IDE)可以从利用反射中可用的类型信息中受益,以帮助程序员编写正确的代码。
调试器和测试工具 :调试器需要能够检查一个类里的私有成员。测试工具可以利用反射来自动地调用类里定义的可被发现的 API 定义,以确保一组测试中有较高的代码覆盖率。
反射的缺点:
尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。在我们使用反射技术时,下面几条内容应该牢记于心。
性能开销 :反射涉及了动态类型的解析,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。
安全限制 :使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如 Applet,那么这就是个问题了。
内部暴露 :由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用,这可能导致代码功能失调并破坏可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。
5.异常
Throwable 可以用来表示任何可以作为异常抛出的类,分为两种: Error 和 Exception。其中 Error 用来表示 JVM 无法处理的错误,Exception 分为两种:
受检异常 :需要用 try...catch... 语句捕获并进行处理,并且可以从异常中恢复;
非受检异常 :程序运行时错误,例如除 0 会引发 Arithmetic Exception,此时程序崩溃并且无法恢复。