标识符
定义Java常量的常用数据类型
- 各进制下的数值:10(十进制)=0xA(16进制)=012(8进制)
- Java中的基本数据类型独立于各平台
整型 :byte(8) short(16) int(32) long(64)
浮点型:float(32) double(64)
使用科学记数法定义浮点值
123.456=1.23456e+2
布尔型:true,false
字符型:‘a’,’A‘
字符串:“hello”
Java7及以上版本允许使用下划线分隔多个数位
import java.text.NumberFormat;
public class welcome1 {
public static void main(String[] args)
{
int number = 1000000;
int number1 = 1_000_000;
System.out.println("number=number1?");
System.out.println(number==number1);
//使用当前区域语言特性格式化数字
NumberFormat format = NumberFormat.getInstance();
System.out.println(format.format(number1));
}
}
定义常量
- 利用关键字final声明常量,对于全局的常量(即在整个项目中都可用),通常按以下模式声明:
public static final int MAX_VAlUE = 512;
- 如果某常量只在本类使用,则应将其定义为private
- 常量名字通常采用大写字母
原始数据类型与类
- Java中除了int、float等少数几个数据类型,其余的数据类型都用来引用对象
- int、float等这些数据类型称为原始数据类型(primitive type)
枚举类型
- 定义:
enum Size{SMALL,MEDIUM,LARGE}
支持JDK5.0及以上版本
- 使用:
public class welcome1 {
enum Size{Small,Medium,Large};
public static void main(String[] args)
{
//System.out.println("Size");
Size t = Size.Large;
//从字串转换为枚举,但是字串必须是Size里有的字串
Size t1= Size.valueOf("Small");
System.out.println(t);
System.out.println(t1);
}
}
The member enum Size can only be defined inside a top-level class or interface or in a static context
- 枚举值的foreach迭代
public class welcome1 {
private enum Size{Small,Medium,Large};
public static void main(String[] args)
{
for(Size value:Size.values())
{
System.out.println(value);
}
}
}
⚠️枚举可用于switch语句中
- 枚举类型不属于原始数据类型,它的每个具体值都引用一个特定的对象。相同的值则引用同一个对象。
- 可以使用”==“和equals()方法直接比对枚举变量的值,换句话说,对于枚举类型的变量,两个方法执行的结果是等价的。
- 枚举类型是引用类型
- Java编程语言中的enum类型实际上派生于java.lang.Enum类型
enum源码
package java.lang;
import java.io.Serializable;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
/**
* This is the common base class of all Java language enumeration types.
*
* More information about enums, including descriptions of the
* implicitly declared methods synthesized by the compiler, can be
* found in section 8.9 of
* <cite>The Java™ Language Specification</cite>.
*
* <p> Note that when using an enumeration type as the type of a set
* or as the type of the keys in a map, specialized and efficient
* {@linkplain java.util.EnumSet set} and {@linkplain
* java.util.EnumMap map} implementations are available.
*
* @param <E> The enum type subclass
* @author Josh Bloch
* @author Neal Gafter
* @see Class#getEnumConstants()
* @see java.util.EnumSet
* @see java.util.EnumMap
* @since 1.5
*/
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
/**
* The name of this enum constant, as declared in the enum declaration.
* Most programmers should use the {@link #toString} method rather than
* accessing this field.
*/
private final String name;
/**
* Returns the name of this enum constant, exactly as declared in its
* enum declaration.
*
* <b>Most programmers should use the {@link #toString} method in
* preference to this one, as the toString method may return
* a more user-friendly name.</b> This method is designed primarily for
* use in specialized situations where correctness depends on getting the
* exact name, which will not vary from release to release.
*
* @return the name of this enum constant
*/
public final String name() {
return name;
}
/**
* The ordinal of this enumeration constant (its position
* in the enum declaration, where the initial constant is assigned
* an ordinal of zero).
*
* Most programmers will have no use for this field. It is designed
* for use by sophisticated enum-based data structures, such as
* {@link java.util.EnumSet} and {@link java.util.EnumMap}.
*/
private final int ordinal;
/**
* Returns the ordinal of this enumeration constant (its position
* in its enum declaration, where the initial constant is assigned
* an ordinal of zero).
*
* Most programmers will have no use for this method. It is
* designed for use by sophisticated enum-based data structures, such
* as {@link java.util.EnumSet} and {@link java.util.EnumMap}.
*
* @return the ordinal of this enumeration constant
*/
public final int ordinal() {
return ordinal;
}
/**
* Sole constructor. Programmers cannot invoke this constructor.
* It is for use by code emitted by the compiler in response to
* enum type declarations.
*
* @param name - The name of this enum constant, which is the identifier
* used to declare it.
* @param ordinal - The ordinal of this enumeration constant (its position
* in the enum declaration, where the initial constant is assigned
* an ordinal of zero).
*/
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
/**
* Returns the name of this enum constant, as contained in the
* declaration. This method may be overridden, though it typically
* isn't necessary or desirable. An enum type should override this
* method when a more "programmer-friendly" string form exists.
*
* @return the name of this enum constant
*/
public String toString() {
return name;
}
/**
* Returns true if the specified object is equal to this
* enum constant.
*
* @param other the object to be compared for equality with this object.
* @return true if the specified object is equal to this
* enum constant.
*/
public final boolean equals(Object other) {
return this==other;
}
/**
* Returns a hash code for this enum constant.
*
* @return a hash code for this enum constant.
*/
public final int hashCode() {
return super.hashCode();
}
/**
* Throws CloneNotSupportedException. This guarantees that enums
* are never cloned, which is necessary to preserve their "singleton"
* status.
*
* @return (never returns)
*/
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
/**
* Compares this enum with the specified object for order. Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
*
* Enum constants are only comparable to other enum constants of the
* same enum type. The natural order implemented by this
* method is the order in which the constants are declared.
*/
public final int compareTo(E o) {
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
}
/**
* Returns the Class object corresponding to this enum constant's
* enum type. Two enum constants e1 and e2 are of the
* same enum type if and only if
* e1.getDeclaringClass() == e2.getDeclaringClass().
* (The value returned by this method may differ from the one returned
* by the {@link Object#getClass} method for enum constants with
* constant-specific class bodies.)
*
* @return the Class object corresponding to this enum constant's
* enum type
*/
@SuppressWarnings("unchecked")
public final Class<E> getDeclaringClass() {
Class<?> clazz = getClass();
Class<?> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
}
/**
* Returns the enum constant of the specified enum type with the
* specified name. The name must match exactly an identifier used
* to declare an enum constant in this type. (Extraneous whitespace
* characters are not permitted.)
*
* <p>Note that for a particular enum type {@code T}, the
* implicitly declared {@code public static T valueOf(String)}
* method on that enum may be used instead of this method to map
* from a name to the corresponding enum constant. All the
* constants of an enum type can be obtained by calling the
* implicit {@code public static T[] values()} method of that
* type.
*
* @param <T> The enum type whose constant is to be returned
* @param enumType the {@code Class} object of the enum type from which
* to return a constant
* @param name the name of the constant to return
* @return the enum constant of the specified enum type with the
* specified name
* @throws IllegalArgumentException if the specified enum type has
* no constant with the specified name, or the specified
* class object does not represent an enum type
* @throws NullPointerException if {@code enumType} or {@code name}
* is null
* @since 1.5
*/
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
}
/**
* enum classes cannot have finalize methods.
*/
protected final void finalize() { }
/**
* prevent default deserialization
*/
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
}
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
}
Java运算符
- 算术运算基本与C一致
public class welcome1 {
public static void main(String[] args)
{
int a=-1;
System.out.println(a<<2);//输出-4
int b=1;
System.out.println(b>>1);//输出0
}//后面数字移动位数,负数补码存储
}
Java中的变量
- 变量可看成是某内存单元(区域)的名字
变量与内存
- 每个变量都有一个名字、数据类型、所占内存单元数和一个值
名字对应于内存中的位置
数据类型决定了它占用的内存单元数量
值表示变量所占用的内存单元中所保存的数据 - 变量的读写:当新值被赋给变量时,老值将被取代,仅从内存中读数据不会破坏数据
变量的使用准则
- 在实际开发中,一般使用变量来存储用户在程序运行时输入的数据
- 变量在使用前应保证它有确切的值
变量的作用域
public class welcome1 {
static int a=1;
public static void main(String[] args)
{
a=2;
System.out.println(a);
}
}
//输出2
public class welcome1 {
public static void main(String[] args)
{
static int a=1; a=2;
System.out.println(a);
}
}//error
Java变量遵循同名变量屏蔽原则,有意识地在不同的地方定义一些同名变量,看看输出的到底是哪个值。
在运行时读取用户输入
方法一:使用JOptionPane类的showInputDialog方法
import javax.swing.JOptionPane;
public static void main(String[] args)
{
String firstname = JOptionPane.showInputDialog("Enter:");
System.exit(0);
}
方法二:使用Scanner类(JDK5.0以上)
Scanner in =new Scanner(System.in);
System.out.println("what is your name ?");
String name = in.nextLine();
- Scanner类有nextInt、nextDouble等方法
变量间的类型转换
自动类型转换是安全的
int intValue = 100;
long longValue = intValue;
强制类型转换时可能会引起信息的损失
double doubleValue = 1234567890;
float floatValue = (float)doubleValue;
System.out.println(floatValue);//1.23456794E9
Java中的类型转换
另一种数据类型转换的方法
- 除了可以使用c的强制类型转换方式,我们还可以通过原始类型的包装类(基本类型封装类)完成转换:
- 适用场景
同一个数据需要转换为多种类型,并且这一数据需要比较长期的使用。多数情况下,推荐直接使用强制类型转换的方式
精度缺失
System.out.println("0.05+0.01="+(0.05+0.01));
System.out.println("1.0-0.42="+(1.0-0.42));
System.out.println("4.015*100="+4.015*100);
System.out.println("123.3/100="+(123.3/100));
输出结果为
0.05+0.01=0.060000000000000005
1.0-0.42=0.5800000000000001
4.015*100=401.49999999999994
123.3/100=1.2329999999999999
原因:十进制数在转换成二进制数的时候,有的数不能用有限的位完全表示出来,在计算的时候就造成了精度缺失。
== 精度缺失处理方法==
Java中提供了大数字(超过16位有效位)的操作类,即java.math.BinInteger类和java.math.BigDecimal类,用于高精度计算。
BinInteger类是针对大整数的处理类,BigDecimal类是针对大小数的处理类
BigDecimal类的实现用到了BigInteger类,不同的是BigDecimal类加入了小数的处理类。
float和Double只能用来作科学计算或是工程计算;在商业计算的时候,必须使用BigInteger和BigDecimal类,它支持任何精度的定点数,可以用它来精确计算货币值。
BigDemical类创建的是对象,不能使用传统的±*/等运算符,必须调用其对应的方法。方法的参数也必须是BigDemical类型的对象
一、构造BigDemical对象常用方法
- 方法一
BigDemical BigDemical (double d);//不推荐使用
- 方法二
BigDemical BigDemical (String s);//常用,推荐使用
- 方法三
static BigDecimal valueOf(double d);//常用。推荐使用
注意:
- double参数的构造方法,不允许使用!!!!因为它不能精确的得到相应的值,值会变大!!!
- String构造方法是完全可预知的;写入new BigDeciaml(”0.1")将创建一个BigDemical,它正好等于预期的0.1;因此通常建议先使用String构造方法
- 静态方法valueOf(double val)内部实现,仍是将double转换为String类型;这通常是将double(或float)转化为BigDemical的首选方法
将double转换成String类型 new BigDecimal (String.valueOf(d));
new BigDecimal(Double.toString(d));
直接调用静态方法
BigDemical.valueOf(d);
BigDemical保留小数位
BigDemical类的几个常用方法
/**
* 求余数
* 返回值为 (this % divisor) 的 BigDecimal
*/
BigDecimal remainder(BigDecimal divisor);
/**
* 求相反数
* 返回值是 (-this) 的 BigDecimal
*/
BigDecimal negate();
/**
* 将此 BigDecimal 与指定的 BigDecimal 比较
* 根据此方法,值相等但具有不同标度的两个 BigDecimal 对象(如,2.0 和 2.00)被认为是相等的;
* 相对六个 boolean 比较运算符 (<, ==, >, >=, !=, <=) 中每一个运算符的各个方法,优先提供此方法;
* 建议使用以下语句执行上述比较:(x.compareTo(y) <op> 0), 其中 <op> 是六个比较运算符之一;
*
* 指定者:接口 Comparable<BigDecimal> 中的 compareTo
* 返回:当此 BigDecimal 在数字上小于、等于或大于 val 时,返回 -1、0 或 1
*/
int compareTo(BigDecimal val);
int x=10;
int y=11;
System.out.println("x+y="+x+y);
System.out.println(x+y+"+x+y");
输出结果
x+y=1011
21+x+y
两种类型的变量
- 引用类型的变量(Reference variables)引用过一个对象(变量本身用于存放对象在内存中的位置,可以看成一个指针),故又被称为“对象变量”)
- 原始数据类型的变量,变量中仅包含数据
作业1:编写一个程序,用户输入两个数,求出其加减乘除,并用消息框显示计算结果。
import javax.swing.JOptionPane; // import class JOptionPane
public class welcome1{
public static void main( String args[] )
{
String firstNumber, // first string entered by user
secondNumber; // second string entered by user
int number1, // first number to add
number2, // second number to add
sum; // sum of number1 and number2
// read in first number from user as a string
firstNumber =
JOptionPane.showInputDialog( "Enter first integer" );
// read in second number from user as a string
secondNumber =
JOptionPane.showInputDialog( "Enter second integer" );
// convert numbers from type String to type int
number1 = Integer.parseInt( firstNumber );
number2 = Integer.parseInt( secondNumber );
// add the numbers
sum = number1 + number2;
// display the results
JOptionPane.showMessageDialog(
null, "The sum is " + sum, "Results",
JOptionPane.PLAIN_MESSAGE );
System.exit( 0 ); // terminate the program
}
}
作业2:自动生成验证码的程序
大概知道为什么要有验证码,但是具体细节还是不了解的所以先查了一下验证码的原理及作用。
验证码的目的
验证码是目前大多数网站所支持并使用于注册登陆的。其作用在于能够有效防止恶意登陆注册,验证码每次都不同就可以排除用其他病毒或者软件自动申请用户及自动登录。
还有一点就是频繁的发送验证码,用户请求注册会提示Xx时间之后再发送验证码,也算是设置了二次防护。
验证码设计成图片的格式也是一种保护,而且一般还是人们肉眼都难以识别其中的验证码。
验证码实现原理
【验证码为什么要设计成图片的格式,而且人们肉眼都难以识别其中的验证码?】
图片是在服务端随机产生,这些图片可以通过设置规定他们的高度和宽度,然后再图片上绘制一些干扰线,当然,干扰线的数量也是可以控制的,不同验证码插件或者不同的网站验证码图片的干扰程度不同,一般来说干扰程度越高,防止恶意攻击的效果会更好一些。但是用户识别起来也会增加难度,制造干扰线也是防止别人编写程序识别图片中的验证码或者通过某种机器提取图片中的验证码,来进行恶意注册或搞破坏。如果人眼都不能一眼轻易识别图片中的验证码,相信机器的识别度在比人眼低的情况下,不容易获取图片中的验证码。图片上的验证码可以是数组和大小写字母的组合,也可以是汉字的形式,这些字符都是随机产生并进行拼接的。实现验证功能的图片合成之后,会转换为一串字符串,然后以字节数组输出流的形式传送到前端,并显示在页面的相应位置。不是,该验证码产生的同时,会伴随产生它的唯一标志的id,过期时间,然后这些数据一般会一同封装到服务端的缓存中,到用户输入验证码并返回时,在服务端进行校验,并把校验的结果返回到前端界面。这些是验证码的大致原理。