java入门(2)

Wesley13
• 阅读 630

类型系统

高级语言都有自己的类型系统。

类型系统可以划分为:强类型,弱类型

或者:静态类型,动态类型。

通俗地说,强类型就是语言比较在意不同类型的区别,会对某个类型所能作的动作进行严格审查,

而弱类型就睁一眼闭一眼,想做什么就做什么,比如c是弱类型,你本来定义了一个int,待会儿可以拿它当double来用,虽然c语言也会抱怨一下,但绝不阻止你。

(她的意思是,你一定要玩火,那就好自为之吧,我管不了)

如果是在编译期间进行这样的检查,就是静态类型。运行时才检查就是动态类型。

java是强类型的,静态类型的。

也就是说,java中很受限制,你定义了某个类型,那就一定按该类型的约束来行事,不能开后门。

如果你想仿照c那样,来点小小的变换技巧什么的,都不用等到运行,java的编译器直接把你毙掉。因为她是静态类型的。

类型系统提供了安全保障,无视类型也能带来灵活性,这取决于你的需求。

比方说,洗衣机能放入什么?当然是衣服了!

被单行不行? 可以。

袜子行不行?可以。

苹果行不行?不行!

如果是c语言,对话是这样的:

你:把苹果放入洗衣机!

c:恐怕不好吧。

你:少废话,让你放就放。

c:那就放了,出什么事你自己负责,别说我不提醒你。

如果是java,对话很简单:

你:把苹果放入洗衣机!

java:办不到!

但编译器必定是傻乎乎的,你可以哄骗它。

你:把苹果放入洗衣机!

java:办不到!

你:把苹果当“物品”看,记为x

java: 没问题

你:现在x是物品了,把它放入洗衣机。

java: 这不行啊,只有“被服”类型的才能放入。

你:那先把 x 转为需要的类型,再放入。

java: 这不好吧,你肯定x是"被服"吗?

你:我肯定,放吧

java: 好吧。

看到了?我们可以说服编译器做一些危险的事。但最好别这样。

编译器是来帮我们防止逻辑错误的,你这样狠心地骗它太残忍了。。。。

所以说,类型还是有用的。

java 的类型系统可以分为两个大类:基本类型和复合类型。

基本类型又叫:简单类型或原生类型。包含:整数,浮点数,字符,布尔型四大类。

而复合类型也叫复杂类型,涉及:类,接口,数组。

我们先从最简单的类型说起。

整型

为了适应不同的场合,java中的整型有4种: byte short int long

它们表示的数的大小范围不同。如果没有特殊的用途,用 int 就好了。这是 4 个字节的类型,可以表示大约20亿左右的有符号的整数。

我们可以在整型上进行 + - * / 和取模(%)运算

例一:

已知一个数字的百位,十位,个位,求这个数字。

public class A
{
    public static void main(String[] args){
        int a = 5;
        int b = 6;
        int c = 9;
        
        int n = a * 100 + b * 10 + c;
        System.out.println(n);
    }
}

这会输出: 569

例二:

已知一个整数,分别输出它的百位,十位,个位。

 1 public class A1
 2 {
 3     public static void main(String[] args){
 4         int n = 2736;
 5         int a = n % 1000 / 100;
 6         int b = n % 100 / 10;
 7         int c = n % 10;
 8         
 9         System.out.println(a);
10         System.out.println(b);
11         System.out.println(c);
12     }
13 }

这会输出:7,3 和 6

println 输出一项后会回车换行。如果不想换行,可以用 print 代替。

也可以先把若干信息拼成一个大串,再输出这个串。

String s = a + "," + b + "," + c;

System.out.println(s);

通过这样的代码来取出各个位,并不会去影响 n 的数值。

如果用一下面的方法,会影响 n 的值。

 1 public class A2
 2 {
 3     public static void main(String[] args){
 4         int n = 2736;
 5         int c = n % 10; n = n / 10;
 6         int b = n % 10; n /= 10;
 7         int a = n % 10;
 8         System.out.println(a);
 9         System.out.println(b);
10         System.out.println(c);
11     }
12 }

一般情况下,我们都是每一行代码一个分号。然而也可以在一行放多条语句。

n % 10 会取出n的最末位来。

n / 10 会求出 n 除以 10 的商来,它的结果还是整数,不会得出类似273.6 的结果来。

n /= 10 与 n = n / 10 的含义是一样的,不过这样写更酷一些。

很多运算符都可以有对应的反身运算,表示对一个变量本身做的某个动作。

n = n 运算 a, 一般都能写成:

n 运算= a;

n *= 100;

就是把 n 乘以 100,再放回到 n 中。

注意,这里的 *= 是一个整体,是一个运算符,中间不能有空格。 

浮点数

浮点类型常用的是 double(8位64bit), 必要的时候当然也可以用float(4位32bit)

浮点数与其它类型的数字的运算结果还是浮点数。

所以可能自动把一个整数数转为浮点数。

double a = 10;  //正确

System.out.println(10/3);   //结果是整数

System.out.println(10/3.0);  //结果是浮点数

浮点数可以被强制转为整数,这样会丢失它的小数部分。

以下代码分别取得一个浮点数的整数部分和小数部分。

 1 public class A3
 2 {
 3     public static void main(String[] args){
 4         double x = 5.81236;
 5         int a = (int)x;
 6         double b = x - a;
 7         System.out.println(a);
 8         System.out.println(b);        
 9     }
10 }

浮点数因为是用有限的空间来存储的,所以存在一个表示精度的问题。

在任何时候都要避免对两个浮点数进行相等性比较。

不信的话,请执行如下代码:

System.out.println(0.1+0.2 == 0.3);

这会输出 false。

但可以这样表达:

System.out.println(Math.abs(0.1+0.2-0.3) < 1e-6);

这意思是说:01+0.2的值与0.3相差不足10的负6次方。就是几乎相等的意思。

这里的1e-6 是科学记数表示法。

java提供了许多数学函数,比如:sin, log 等方便我们运算,都在Math对象中,是静态方法。

System.out.println(Math.sin(30 * Math.PI/180));  //单位度需要转为弧度。

浮点数的输出一般要求保留到小数后的多少位。

有很多方法,比如,可以通过String 类的format方法,类似于c语言的 printf

 这里的需求其实是2种:

一是不希望改变那个浮点数的真实值,只是在显示的时候,不要显示那么啰嗦冗长的小数,希望简短点而已。

这代表了绝大多数的需求,正是用String.format的时机。

1 public class A4
2 {
3     public static void main(String[] args){
4         double a = Math.sin(0.2);
5         System.out.println(a);
6         System.out.println(String.format("%.3f",a));
7     }
8 }

结果为:

java入门(2)

二是需要真实地修改那个浮点数,丢弃多余的小数部分。比如,银行存折上的余额计入利息后,只能四合五入到分,不能有更多的小数。

这时,我们只需要一个小技巧,你自己研究一下吧。

double a = Math.sin(0.15);
System.out.println(a);
double b = (int)(a * 100 + 0.5)/100.0;
System.out.println(b);

字符类型

java中的字符类型存储的是它的unicode码。每个字符用了2个字节,这点与c语言是不同的。

既然是unicode码,那它与整数就有天然的关系。

字符类型可以直接赋值给整数,整数也可以赋值给字符类型(不过需要一个强制转换)

char x = 'A';
System.out.println(x);
int n = x;
System.out.println(n);
System.out.println((char)97);

字符如果是一个十进制的数码,可以把它转换为对应的真值,这个技巧十分常用。

char x = '5';
int k = x - '0';
System.out.println(k);

这是因为十进制的数码字符,它们的unicode码是连续的,并且是有规律的。

布尔型

布尔型表示是否的概念,只有两个值:true和false

布尔值一般作为循环和分支的判断条件。

有些运算会产生出布尔值。

boolean x = 5 >= 3;
boolean y = 1+2==3;
boolean z = "abcd".equals("ABCD");

布尔值本身也会通过逻辑运算符产生出新的布尔值。

&& 逻辑与

|| 逻辑或

! 逻辑非

逻辑运算符具有一个十分重要的特性---短路求值。

if(x>0 && f(x)==5) ....

这句话在 x<=0 的情况下, f(x) 是不会去执行的。

因为,x>0 是 false, 而 false && 任何东西都是false,那么表达式的值就一定是false,也就没有必要再计算下去了。

字符串

字符串并非是基本类型,它属于java的面向对象体系。

String 是类名,new String() 创建出字符串对象。

"abc" 是字符串常量。

String s = "abc";

这里的 s 并不是字符串本身,它是指向字符串的引用,相当于c语言中的指针。

所以,如果:

String s2 = s;

这时,并非有两个字符串,而是有两个引用指向了同一个字符串。

字符串是不可变的对象,也就是说,字符串一旦形成,它的内容不可更改!

但,我们可以生生成新的字符串,并把旧的字符串丢弃。

例如:

String s = "abc";
s = s + "de";
System.out.println(s);

这里,s开始的时候指向了字符串对象,内容是"abc",后来,把 "abc" 与 "de"进行了拼接操作,生成了新的字符串对象 "abcde"。

然后,s 引用放弃了先前的对象,指向了新生成的对象,内容是:"abcde"

字符串类型与字符类型的关系当然最为密切。

因为字符串正是由字符构成的。

字符串类中提供了丰富的方法,可以对串进行各种常见的操作。

String s = "123456";
int n = s.length();
char x = s.charAt(n-1);

如此操作,则 n 中存储了字符串的长度,

x 中存储了最后一个字符,即:'6'

String s1 = s.substring(0,3);
String s2 = s.substring(3);

s1 指向了新串,它是 s 的一个子串,内容: "123"

substring方法的两个参数是:开始位置的下标,结束位置的下标。

这里要注意,规则是:包含开始,不包含结束。

我们也可以判断一个串是否包含某个子串:

int k = s.indexOf("34");

这会返回子串 "34" 在母串中的第一次出现的位置。

如果找不到,就会返回-1。

字符串可能是我们最常用的复合类型了,它还有一个很有趣的特性:

任何类型都可以和一个串做加法,其动作就是和那个串拼接起来。

String s = "" + 1 + 2 + (5>3) + 'A';
System.out.println(s);
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Easter79 Easter79
3年前
typeScript数据类型
//布尔类型letisDone:booleanfalse;//数字类型所有数字都是浮点数numberletdecLiteral:number6;lethexLiteral:number0xf00d;letbinaryLiteral:number0b101
皕杰报表(关于日期时间时分秒显示不出来)
在使用皕杰报表设计器时,数据据里面是日期型,但当你web预览时候,发现有日期时间类型的数据时分秒显示不出来,只有年月日能显示出来,时分秒显示为0:00:00。1.可以使用tochar解决,数据集用selecttochar(flowdate,"yyyyMMddHH:mm:ss")fromtablename2.也可以把数据库日期类型date改成timestamp
Karen110 Karen110
3年前
​一篇文章总结一下Python库中关于时间的常见操作
前言本次来总结一下关于Python时间的相关操作,有一个有趣的问题。如果你的业务用不到时间相关的操作,你的业务基本上会一直用不到。但是如果你的业务一旦用到了时间操作,你就会发现,淦,到处都是时间操作。。。所以思来想去,还是总结一下吧,本次会采用类型注解方式。time包importtime时间戳从1970年1月1日00:00:00标准时区诞生到现在
待兔 待兔
4年前
Flutter开发必备Dart基础:Dart快速入门
<h1概述</h1<pDart从2.0开始变为强类型语言,静态类型。这点和Java、C等比较相似。也就是说在编译时就已经知道变量的类型那么就是静态类型语言。开发人员在开发的时候需要指定变量的类型。这有什么优点呢?就是所有类型检查都可以通过编译器来完成。可以提前预报一些琐碎的错误。<br同时Dart还是面向对象的编程语言。像python、Java、Kol
Stella981 Stella981
3年前
Python将字符串转换成ObjectId类型
MongoDB自动生成的_id是ObjectId类型的。我需要将MongoDB的_id存到ElasticSearch中,而ElasticSearch又只能存String类型的_id,所以就涉及到两种类型的转换。ObjectId类型—→String类型这个非常简单
Wesley13 Wesley13
3年前
Java中的基本数据类型和引用数据类型的区别
一、前言众所周知Java是一种强类型语言,在Java语言中,Java的数据类型一共分为两大类,分别为基本数据类型和引用数据类型,其中基本数据类型细分小类可分为整数类型、浮点类型、字符类型、布尔类型这四小类。二、基本数据类型和引用数据类型1\.基本数据类型只有
Wesley13 Wesley13
3年前
mysql中时间比较的实现
MySql中时间比较的实现unix\_timestamp()unix\_timestamp函数可以接受一个参数,也可以不使用参数。它的返回值是一个无符号的整数。不使用参数,它返回自1970年1月1日0时0分0秒到现在所经过的秒数,如果使用参数,参数的类型为时间类型或者时间类型的字符串表示,则是从1970010100:00:0
Wesley13 Wesley13
3年前
ThinkPHP 根据关联数据查询 hasWhere 的使用实例
很多时候,模型关联后需要根据关联的模型做查询。场景:广告表(ad),广告类型表(ad\_type),现在需要筛选出广告类型表中id字段为1且广告表中status为1的列表先看关联的设置部分 publicfunctionadType(){return$thisbelongsTo('A