基础一:一切都是对象
概述
OOP-面向对象编程(Object Oriented Programming),在Java中(几乎)一切都是对象。
用引用操作对象
在Java中一切都是被看作为对象,因此可以采用单一固定的语法。
尽管一切都看做对象,但操作的标示符实际上仅仅是对象的一个“引用”(reference)。
如果想操作一个字符串,则可以创建一个String 引用:
String s ;
但是这里创建的仅仅是引用,而不是对象。因此如果要操作s,这会返回错误。这是因为s实际上并没有与任何对象关联.
错误如下所示:
因此一种安全的做法就是:创建一个引用的同时便进行初始化
String s = "abc";
必须由你创建所有对象
一旦创建了一个引用,就希望它能与一个新的对象相关联。
通常使用new操作符来实现这一目的。比如
String s = new String("abc");
存储到什么位置
程序运行时,对象是怎样放置安排的呢? 特别是内存是怎样分配的呢?
其实有五个不同的地方可以存储数据:
名称 | 说明 |
---|---|
寄存器 | 最快的存储区,位于存储器内部,但是寄存器的数量极其有限,按需分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。 |
堆栈 | 位于通用RAM(随机访问存储器)中,但通过堆栈指针可以从处理器那里获得直接支持。堆栈指针向下移动—>分配新的内存,向上移动—>释放内存。这种分配存储的方法效率仅次于寄存器。 一般来讲,引用存放在堆栈中,Java对象并不存储在其中。 |
堆 | 一种通用的内存池(也位于RAM中),用于存放所有的Java对象。堆不同于堆栈的好处是:编译器不需要知道存储的数据在堆里存活多长时间。 因此在堆里分配存储有很大的灵活性。这种灵活性必须付出相应的代价:比用堆栈进行分配存储需要更多的时间 |
常量存储 | 常量值通常存放在程序代码内部,永远不会被改变。 |
非RAM存储 | 数据完全存活于程序之外,比如 流对象 和 持久化对象。 |
特例:基本类型
在程序设计中常用到一系列类型,他们需要特殊对待,可以把他们想象成基本类型。
之所以特殊对待,是因为new将对象存储在“堆”中,故用new创建一个对象–特别是小的、简单的变量,往往不是很有效。
因此,Java采用了和C,C++相同的方法,也就是不用new创建,而是创建一个并非是引用的“自动“变量。 这个变量直接存储”值“,并置于堆栈中,因此更高效。
Java要确定每种基本类型所占存储控件的大小,它们的大小并不像其他语言那样随着机器硬件架构的变化而变化。
基本类型 | 大小 | 最小值 | 最大值 | 包装类型 |
---|---|---|---|---|
boolean | – | – | – | Boolean |
char | 16-bit | Unicode 0 | Unicode 2^16-1 | Character |
byte | 8-bits | -128 | +127 | Byte |
short | 16-bits | -2^15 | +2^15-1 | Short |
int | 32-bits | -2^31 | +2^31-1 | Integer |
long | 64-bits | -2^63 | +2^63-1 | Long |
float | 32-bits | IEEE754 | IEEE754 | Float |
double | 64-bits | IEEE754 | IEEE754 | Double |
void | – | – | – | Void |
基本类型具有的包装器类,使得可以在堆中创建一个非基本的对象,用来表示对应的基本类型。比如:
char c = 'x';
Character ch = new Character(c);
或者:
Character ch = new Character('x');
Java SE5的自动包装功能自动的将基本类型转换为包装器类型
Character ch = 'x';
并可以反向转换:
char c = ch;
高精度数字:
Java提供了2个高精度计算的类
BigInteger BigDecimal.
虽然他们大体上属于包装器类的范畴,但是却没有对应的基本类型。
这两个类都有自己的一系列方法,类似于我们针对主类型执行的操作,也就是说能用 int 或float 做的事情,用BigInteger和BigDecimal 一样可以做,只是必须换用方法调用,而不是使用运算符。此外由于牵涉更多,所以运算速度会慢一点总之我们牺牲了速度,但换来了精度。
BigInteger支持任意精度的整数,也就是说我们可精确表示任意大小的整数值;同时在运算过程中不会丢失任何信息;
在BigInteger类中有所有的基本算术运算方法,如加、减、乘、除,以及可能会用到的位运算如或、异或、非、左移、右移等。
从数值上比较两个 BigDecimal 值时,应该使用 compareTo() 而不是 equals()。
要小心使用 BigDecimal(double) 构造函数, 因为如果不了解它,会在计算过程中产生舍入误差。请使用基于整数或 String 的构造函数。
由于 BigDecimal 对象是不可变的,这些方法中的每一个都会产生新的 BigDecimal 对象。因此,因为创建对象的开销,BigDecimal 不适合于大量的数学计算,但设计它的目的是用来精确地表示小数。如果您正在寻找一种能精确表示如货币量这样的数值,则 BigDecimal 可以很好地胜任该任务。
永远不需要销毁对象
作用域
作用域由花括号的位置决定。
{// x availableint x = 12 ;System.out.println("x:" + x );{// Both x & y availableint y = 9 ;System.out.println("x:" + x + ",y:" + y);}// only x availableSystem.out.println("x:" + x );}
在作用域中定义的变量只可用于作用域结束之前。
对象的作用域
Java对象不具备和基本类型一样的生命周期。
当使用new创建一个java对象时,它可以存活于作用域之外。
比如
{String s = new String("sss");
}// end of scope
引用s在作用域终点就消失了,但是s指向的对象任然占据这内存空间。
我们无法在这个作用域之后访问这个对象,因为对它唯一的引用已经超出了作用域的范围。
事实证明,由new创建的对象,只要你需要就会一直保留下去。
那java如何防止这些对象填满内存空间,进而阻塞你的程序呢?
Java中有一个垃圾回收器,用来监视用new创建的所有对象,并辨别那些不会被再引用的对象。随后,释放这些对象占用的内存空间,以便提供给其他新的对象使用。
创建新的数据类型:类
如果一切都是对象,那什么决定了某一类对象的外观和行为呢? 换句话说 什么确定了对象的类型?
在Java中使用class这个关键字
class ATypeName {// class body gose here
}
实例化
ATypeName a = new ATypeName();
字段和方法
一旦定义了一个类,就可以在类中设置两种类型的元素:字段+方法。
字段可以是任何类型的对象,可以通过起引用与其进行通信;也可以是基本类型中的一种。
如果字段是某个对象的引用,那么必须初始化该引用,以便使其与一个实际的对象相关联。
每个对象都有用来存储其字段的空间; 普通字段不能在对象间共享。
class DataOnly{int i ;double d ;boolean b ;}
尽管这个类除了存储数据之外什么也不能做,但是依然可以创建它的一个对象:
DataOnly data = new DataOnly();
可以给字段赋值,但首先必须知道如何引用一个对象的成员:
objectReference.member
例如:
data.i = 10;
data.d = 1.1;
data.b = false;
基本成员默认值
若类的某个成员是基本类型数据,即使没有初始化,Java会确保它有一个默认值。
当变量作为类的成员变量使用时,Java才确保给定其默认值,以确保那些是基本类型的成员变量得到初始化,防止产生程序错误。
不过最好明确的对变量进行初始化。
上述确保初始化的方法并不适用于“局部变量”(即并非某个类的字段)。
如下:
在某个方法中定义
int x ;
这是不会被自动化初始为0 ,如果未明确的赋值,在编译时会抛出异常
方法、参数和返回值
Java的方法决定了一个对象能接收什么样的的消息。 参数列表给出了要传给方法的信息的类型和名称。 方法名和参数列表唯一的标识出某个方法。
Java中的方法只能作为类的一部分创建。 方法只能通过对象才能被调用(static方法是针对类调用的,并不依赖于对象的存在),且这个对象必须能执行这个方法的调用。
如下:
objectName.methodName(arg1,arg2,arg3);
参数列表
像java中任何传递对象的场合一样,这里传递的实际上也是引用(对于基本类型是一个类外。通常尽管传递的是对象,而实际上传递的对象的引用。)
并且引用的类型必须正确。
比如 参数类型为String ,则必须传递一个String对象,否则编译器抛出异常。
假设某个方法接收String为其参数,具体定义如下,该方法必须置于某个类的定义内才能被正确的编译。
int storage(String s){return s.length();
}
通过上面的例子,我们还可以了解到return关键字的用法。
- 代表已经执行完毕,离开此方法
- 如果该方法有返回值,需要放到return后
boolean flag(){ return true;}
double naturalLogBase(){ return 2.879;}void nothing(){return ;}
void nothing2(){}
若返回类型是void ,return关键字的作用只是用来退出方法。因此没有必要到方法结束时才离开,可以在任何地方离开。
但如果返回类型不是void ,无论在何处返回,编译器都会强制返回一个正确类型的返回值。
static关键字
通常来说,当创建一个类时,就是在描述那个类的对象的外观与行为。
除非用new创建那个类的对象,否则,实际上并没有获取到任何对象, 执行new 来创建对象时,数据存储空间才能被分配,其方法才能被外界调用。
有两种情况是以上方法无法解决的:
1. 只想为某特定域分配单一存储空间,而不考虑究竟要创建多少对象,甚至根本就不创建对象。
2. 第二种情况是:希望某个方法不与包含它的类的任何对象关联在一起,也就是说,即使没有创建对象,也能够调用该方法。
通过static关键字可以满足这两方面的需求。
当声明一个事物是static时,也就意味着这个域或者方法不会与包含它的那个类的任何对象实例关联子啊一起, 所以即使从未创建某个类的任何对象,也可以通过调用其static方法或者访问其static域。
通常你必须创建一个对象,并且用它来访问数据或者方法,因为非static域和方法必须知道他们一起运作的特定对象。
只需要将static关键字放在定义之前,就可以将字段或者方法设定为static
例如
class StaticTest{static int i = 5;
}
即使我们创立了两个StaticTest对象,StaticTest.i也只有一份存储空间,这两个对象共享同一个i.
在这里 a.i和b.i都指向同一个存储空间。
引用static变量的两种方法:
- 可以通过一个对象去引用它,比如 上面中的 a.i
- 也可以通过类名直接引用,而这对于非静态成员则不行,比如
Demo21.i == Demo21.i
这种方式是首选方式,推荐使用这种方式。
类似逻辑同样也适用于 静态方法。
基础一:一切都是对象相关推荐
- 对象存储使用案例_连云数据都有“对象存储”了,你还是单身?
没错,对象存储(OOS,Object-Oriented Storage)可不是一项"在你嫌男票/女票烦的时候暂时寄存的服务",而是中国电信为客户提供的一种海量.弹性.高可靠.高性价 ...
- javascript基础教程_JavaScript基础教程(九)对象、类的定义与使用
对象.类的定义与使用 对象与类是面向对象程序设计语言教学过程中不可避免需要讲解的内容之一.很多人将两者混为一谈,简单认为对象就是类,类就是对象.实际上深入分析的话,对象与类的区别还是较为明显的.本文主 ...
- 命名空间_python基础 13 类命名空间于对象、实例的命名空间,组合方法
python基础 13 类命名空间于对象.实例的命名空间,组合方法 1.类命名空间于对象.实例的命名空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两 ...
- java 注解 对象_Java基础-学习使用Annotation注解对象
Java基础-学习使用Annotation注解对象 注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某 个时刻非常方便地使用这些数据 1-1:基本语法 Java S ...
- Python 3基础语法知识点都在这里了,如果还不能入门就不能怪我了
简介 Python 是一种高层次的结合了解释性.编译性.互动性和面向对象的脚本语言.Python 由 Guido van Rossum 于 1989 年底在荷兰国家数学和计算机科学研究所发明,第一个公 ...
- 细读 Thinking in Java (一)一切都是对象
前言 <Thinking in Java>做为Java最经典的学习书籍之一,不论是对于学习java的新手或是有一定经验的程序员来说都有不同的学习价值,在工作的这两年多当中由于种种杂事一直没 ...
- JS基础学习第六天:JavaScript对象入门(构造函数和实例对象)
在 JavaScript 中,大多数事物都是对象, 从作为核心功能的字符串和数组,到建立在 JavaScript 之上的浏览器 API.你甚至可以自己创建对象,将相关的函数和变量封装打包成便捷的数据容 ...
- python里的类与一切事物都是对象
对于python,一切事物都是对象,对象基于类创建 列如 name='csdcs' li=[1,3,43] 上面两个都是对象,因为它们都是python中的 类里面存着许多的功能,功能的集合, ...
- 一切都是对象---JAVA编程思想
一切都是对象 "如果我们说另一种不同的语言,那么我们就会发觉一个有些不同的世界."--Luduing Wittgerstein(1889-1951) 尽管Java是基于C++的,但 ...
- 深入理解javascript原型和闭包(1)——一切都是对象
"一切都是对象"这句话的重点在于如何去理解"对象"这个概念. 当然,也不是所有的都是对象,值类型就不是对象. 首先咱们还是先看看javascript中一个常用的 ...
最新文章
- 突然想起99年的那次离别
- 究竟使用什么样的万向轮?
- 达梦数据库DM8飞腾版本、芯版本获取地址,最新达梦数据库各国产化版本获取方法,达梦数据库DM8使用手册、产品文档获取
- http://udacity.com 和 https://www.udemy.com 请注意区分!
- 【图像超分辨率】基于ResNet或GAN的遥感图像超分辨率论文
- 1.3编程基础之算术表达式与顺序执行 06 甲流疫情死亡率
- SQL优化的思路及基本原则(mysql)
- 安装VS2008关于解决磁盘已满问题方案.
- Android IPC通信系列篇
- 转载:用图片搜索图片的几个好网站
- chrome最简单的多开方法
- OSG中osg::ref_ptf类的巧妙设计
- 蓝牙音箱延迟测试软件,“Latency Test”详细操作流程,一款测试TWS耳机延迟的软件...
- 实现短信验证码有效时间
- 12 个最佳的免费学习编程的游戏网站
- WebGL 绘制Line的bug(一)
- gunicorn 安装部署详解
- 计算机专业要学视频剪辑吗,想要成为入门剪辑师?必须做到这五点,才能坚持下去...
- 华为董事会名单大曝光:孙亚芳任正非等13名董事
- 读取盘序列号(是物理序列号,不是硬盘扇区上的序列号)在win7下的确不能用了
热门文章
- 如何自学Java 经典
- Vitalik:ETH2.0 之后,协议层会稳定下来
- 2017北大数学夏令营第一天第二题的解答
- 瑞士轮赛制模拟器_【入门必读】VGC综合介绍(下篇)【翻译】
- Amazon Alexa系列介绍(3)--Alexa Voice Service API介绍
- 微信支付-商家给小程序用户转账教程(全网最详细JAVA版)
- 元宇宙011 | 元宇宙的沉浸式体验会成瘾吗?
- MySQL更新时间的时候生成随机时间
- 广义相对论和量子力学在哪些地方发生了严重的冲突(转)
- 如何设置 RecyclerView Item内子控件点击事件