public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2); //true
System.out.println(i3==i4); //false
}
}
为什么会这样呢?看下Integer的valueOf方法的具体实现:
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
而其中IntegerCache类的实现为:
private static class IntegerCache {
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
public class Main {
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
System.out.println(c==d); //true
System.out.println(e==f); //false
System.out.println(c==(a+b)); //true
System.out.println(c.equals(a+b)); //true
System.out.println(g==(a+b)); //true
System.out.println(g.equals(a+b)); //false
System.out.println(g.equals(a+h)); //true
}
}
equals()方法源码
//Integer类中
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
//Long类中
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
/*
* 季节类
* 有且仅有4个对象,且对象的属性是固定的
* 手动实现枚举类
*/
public class Season {
//季节属性:属性是固定的(外界不可访问,当前类不可以修改)
private final String SEASON_NAME;
private final String SEASON_DESC;
//对象只能由本类提供
private Season(String season_name, String season_desc) {
this.SEASON_NAME = season_name;
this.SEASON_DESC = season_desc;
}
public String getSEASON_NAME() {
return SEASON_NAME;
}
public String getSEASON_DESC() {
return SEASON_DESC;
}
//在本类中创建4个季节对象(不能修改)
public static final Season SPRING = new Season("春天","雨想衣裳花想荣,春风芙兰露华荣");
public static final Season SUMMER = new Season("夏天","接天莲花无穷尽,映日荷花别样红");
public static final Season OUTUMN = new Season("秋天","月落乌啼霜满天,江枫渔火对愁眠");
public static final Season WINTER = new Season("冬天","忽如一夜春风来,千树万树梨花开");
@Override
public String toString() {
return "Season [SEASON_DESC=" + SEASON_DESC + ", SEASON_NAME="
+ SEASON_NAME + "]";
}
}
测试:
public classs Test{
public static void main(String[] args){
//获取Season对象
Season s = Season.SPRING;
System.out.println(s);
}
}
/*
运行结果为:
Season [SEASON_DESC=雨想衣裳花想荣,春风芙兰露华荣, SEASON_NAME=春天]
*/
public class Test{
public static void main(String[] args){
//获取Season对象
SeasonEnum s = SeasonEnum.SUMMER;
System.out.println(s);
}
}
/*
运行结果为:
Season [SEASON_DESC=雨想衣裳花想荣,春风芙兰露华荣, SEASON_NAME=春天]
*/
public class Test{
public static void main(String[] args){
//获取所有枚举对象
SeasonEnum[] seasons = SeasonEnum.values();
for (SeasonEnum se : seasons) {
System.out.println(se);
}
//将字符串转成枚举对象
String s = "SPRING";
//参数1:枚举类型;参数2:对应字符串
SeasonEnum se = Enum.valueOf(SeasonEnum.class, s);
System.out.println(se.getDeclaringClass());
System.out.println(se);
System.out.println(se.name());
//返回枚举常量所在位置
System.out.println(se.ordinal());
}
}
/*
运行结果:
Season [SEASON_DESC=雨想衣裳花想荣,春风芙兰露华荣, SEASON_NAME=春天]
Season [SEASON_DESC=接天莲花无穷尽,映日荷花别样红, SEASON_NAME=夏天]
Season [SEASON_DESC=月落乌啼霜满天,江枫渔火对愁眠, SEASON_NAME=秋天]
Season [SEASON_DESC=忽如一夜春风来,千树万树梨花开, SEASON_NAME=冬天]
class se02.day07.enumdemo.SeasonEnum
Season [SEASON_DESC=雨想衣裳花想荣,春风芙兰露华荣, SEASON_NAME=春天]
SPRING
0
*/
interface Inter {
String getInfo();
}
public enum SeasonEnumImpl implements Inter{
//枚举类的实例,必须要在最前面给出
SPRING("春天","雨想衣裳花想荣,春风芙兰露华荣"),
SUMMER("夏天","接天莲花无穷尽,映日荷花别样红"),
OUTUMN("秋天","月落乌啼霜满天,江枫渔火对愁眠"),
WINTER("冬天","忽如一夜春风来,千树万树梨花开");
//属性:固定,不可修改
private final String SEASON_NAME;
private final String SEASON_DESC;
public String getSEASON_NAME() {
return SEASON_NAME;
}
public String getSEASON_DESC() {
return SEASON_DESC;
}
private SeasonEnumImpl(String season_name, String season_desc) {
SEASON_NAME = season_name;
SEASON_DESC = season_desc;
}
public String toString() {
return "Season [SEASON_DESC=" + SEASON_DESC + ", SEASON_NAME="
+ SEASON_NAME + "]";
}
@Override
public String getInfo() {
switch(this){
case SPRING:
return "春天";
case SUMMER:
return "春天";
case OUTUMN:
return "春天";
case WINTER:
return "春天";
}
return null;
}
}
测试:
public class Test{
public static void main(String[] args){
String info = SeasonEnumImpl.SPRING.getInfo();
System.out.println(info);
}
}
运行结果为: 春天
示例2:采用匿名内部类的方式实现接口
public enum SeasonEnumImpl02 implements Inter{
//枚举类的实例,必须要在最前面给出
SPRING("春天","雨想衣裳花想荣,春风芙兰露华荣"){
@Override
public String getInfo() {
return "春天";
}
},
SUMMER("夏天","接天莲花无穷尽,映日荷花别样红"){
@Override
public String getInfo() {
return "夏天";
}
},
OUTUMN("秋天","月落乌啼霜满天,江枫渔火对愁眠"){
@Override
public String getInfo() {
return "秋天";
}
},
WINTER("冬天","忽如一夜春风来,千树万树梨花开"){
@Override
public String getInfo() {
return "冬天";
}
};
//属性:固定,不可修改
private final String SEASON_NAME;
private final String SEASON_DESC;
public String getSEASON_NAME() {
return SEASON_NAME;
}
public String getSEASON_DESC() {
return SEASON_DESC;
}
private SeasonEnumImpl02(String season_name, String season_desc) {
SEASON_NAME = season_name;
SEASON_DESC = season_desc;
}
public String toString() {
return "Season [SEASON_DESC=" + SEASON_DESC + ", SEASON_NAME="
+ SEASON_NAME + "]";
}
}
测试:
public class Test{
public static void main(String[] args){
SeasonEnumImpl02[] ses = SeasonEnumImpl02.values();
for (SeasonEnumImpl02 se : ses) {
System.out.println(se.getInfo());
}
}
}
public class Client {
public void methodA(String str,Integer... is){
}
public void methodA(String str,String... strs){
}
public static void main(String[] args) {
Client client = new Client();
client.methodA("China", 0);
client.methodA("China", "People");
client.methodA("China"); //compile error
client.methodA("China",null); //compile error
//可修改为
String[] strs = null;
client.methodA("China",strs);
}
}
②覆写变长方法也要循规蹈矩
// 基类
class Base {
void print(String... args) {
System.out.println("Base......test");
}
}
// 子类,覆写父类方法
class Sub extends Base {
@Override
void print(String[] args) {
System.out.println("Sub......test");
}
}
public class VarArgsTest2 {
public static void main(String[] args) {
// 向上转型
Base base = new Sub();
base.print("hello");
// 不转型
Sub sub = new Sub();
sub.print("hello"); //compile error
}
}
第一个能编译通过,这是为什么呢?事实上,base 对象把子类对象 sub 做了向上转型,形参列表是由父类决定的,当然能通过。而看看子类直接调用的情况,这时编译器看到子类覆写了父类的 print 方法,因此肯定使用子类重新定义的 print 方法,尽管参数列表不匹配也不会跑到父类再去匹配,因为找到了就不再找了,因此有了类型不匹配的错误。
isAssignableFrom(Class> cls) 判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。
boolean
isEnum() 当且仅当该类声明为源代码中的枚举时返回 true。
boolean
isInstance(Object obj) 判定指定的 Object 是否与此 Class 所表示的对象赋值兼容。
boolean
isInterface() 判定指定的 Class 对象是否表示一个接口类型。
boolean
isLocalClass() 当且仅当底层类是本地类时返回 true。
boolean
isMemberClass() 当且仅当底层类是成员类时返回 true。
boolean
isPrimitive() 判定指定的 Class 对象是否表示一个基本类型。
T
newInstance() 创建此 Class 对象所表示的类的一个新实例。
String
toString() 将对象转换为字符串。
示例:
package se02.day07.reflect;
public class Person {
private String name;
int age;
public String address;
public Person() {
}
private Person(String name) {
this.name = name;
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public void show() {
System.out.println("show");
}
public void method(String s){
System.out.println("method"+s);
}
public String getString(String s,int i){
return s+"----"+i;
}
private void function() {
System.out.println("function");
}
@Override
public String toString() {
return "Person [address=" + address + ", age=" + age + ", name=" + name
+ "]";
}
}
package se02.day07.reflect;
public class ReflectDemo01 {
public static void main(String[] args) {
//方式1
Person p = new Person();
Class c = p.getClass();
System.out.println(c);
//方式2
Class c2 = Person.class;
System.out.println(c2);
//方式3
try {
Class c3 = Class.forName("se02.day07.reflect.Person");
System.out.println(c3);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
输出结果:
class se02.day07.reflect.Person class se02.day07.reflect.Person class se02.day07.reflect.Person
Field类:提供类的成员变量信息,就是类的属性。
方法摘要:
boolean
equals(Object obj) 将此 Field 与指定对象比较。
Object
get(Object obj) 返回指定对象上此 Field 表示的字段的值。
String
getName() 返回此 Field 对象表示的字段的名称。
short
getShort(Object obj) 获取 short 类型或另一个通过扩展转换可以转换为 short 类型的基本类型的静态或实例字段的值。
Class>
getType() 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
void
set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
package se02.day07.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
//通过反射获取成员变量并使用
public class ReflectDemo04 {
public static void main(String[] args) throws Exception {
Class c = Class.forName("se02.day07.reflect.Person");
//Filed[] getFileds():获取所有公共的成员变量
//获取所有的成员变量
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
//通过无参构造创建一个对象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
//获取单个成员变量(公共)
//获取address
Field addressField = c.getField("address");
addressField.set(obj, "上海");
System.out.println(obj);
//获取name,并赋值(私有)
Field nameField = c.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(obj, "老王");
System.out.println(obj);
//获取age,并赋值(默认default)
Field ageField = c.getDeclaredField("age");
ageField.set(obj, 55);
System.out.println(obj);
}
}
输出结果:
private java.lang.String se02.day07.reflect.Person.name int se02.day07.reflect.Person.age public java.lang.String se02.day07.reflect.Person.address Person [address=上海, age=0, name=null] Person [address=上海, age=0, name=老王] Person [address=上海, age=55, name=老王]
public java.lang.String se02.day07.reflect.Person.toString() public java.lang.String se02.day07.reflect.Person.getString(java.lang.String,int) public void se02.day07.reflect.Person.method(java.lang.String) public void se02.day07.reflect.Person.show() public final void java.lang.Object.wait() throws java.lang.InterruptedException public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException public boolean java.lang.Object.equals(java.lang.Object) public native int java.lang.Object.hashCode() public final native java.lang.Class java.lang.Object.getClass() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll() ================================== public java.lang.String se02.day07.reflect.Person.toString() private void se02.day07.reflect.Person.function() public java.lang.String se02.day07.reflect.Person.getString(java.lang.String,int) public void se02.day07.reflect.Person.method(java.lang.String) public void se02.day07.reflect.Person.show() show ============================== methodhello function
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GenericDemo01 {
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
list.add(100);
Iterator iter = list.iterator();
while(iter.hasNext()){
String s = iter.next();
System.out.println(s);
}
}
}
毫无疑问,程序的运行结果会以崩溃结束:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at se01.day05.GenericDemo01.main(GenericDemo01.java:18)
List list = new ArrayList();
...
//list.add(100); 在编译阶段,编译器就会报错
实例2:
//泛型类
class ObjectDemo{
private E e;
public void setE(E e){
this.e = e;
}
public E getE(){
return e;
}
}
//不使用泛型
class ObjectDemo02{
private Object obj;
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
public class GenericDemo02 {
public static void main(String[] args) {
ObjectDemo od = new ObjectDemo();
od.setE("张伟");
System.out.println(od.getE());
ObjectDemo od2 = new ObjectDemo();
od2.setE(12);
int i = od2.getE();
System.out.println(i);
ObjectDemo02 obj = new ObjectDemo02();
obj.setObj("最低配");
// Integer inter = (Integer) obj.getObj();//.ClassCastException
// System.out.println(inter);
}
}
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic{ //一个类上可以定义多种泛型声明
//key这个成员变量的类型为T,T的类型由外部指定
private T key;
public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定
this.key = key;
}
public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定
return key;
}
public R fun(T p){ //R是返回值类型,T为方法参数类型
teturn null;
}
}
测试:
public class GenericTest{
public static void main(String[] args){
//泛型的类型参数只能是类类型(包括自定义类),不能是简单类型
//传入的实参类型需与泛型的类型参数类型相同,即为Integer.
Generic genericInteger = new Generic(123456);
//传入的实参类型需与泛型的类型参数类型相同,即为String.
Generic genericString = new Generic("key_vlaue");
System.out.println("泛型测试","key is " + genericInteger.getKey());
System.out.println("泛型测试","key is " + genericString.getKey());
}
}
输出结果:
泛型测试: key is 123456
泛型测试: key is key_vlaue
泛型类的所有实例都具有相同的运行时类,而不管它们的实际类型参数如何。
实例:
List l1 = new ArrayList();
List l2 = new ArrayList();
System.out.println(l1.getClass()== l2.getClass()); //true
//泛型方法
class Generic{//这个类是个泛型类,在上面已经介绍过
private T key;
//这只是类中一个普通的成员方法,只不过他的返回值是在声明泛型类已经声明过的泛型。
public T getKey(){
return key;
}
/* 因为在类的声明中并未声明泛型K,所以在使用K做形参和返回值类型时,编译器会无法识别。
* K cannot be resolved to a type
* public K setKey(K key){
this.key = key;
}*/
//在泛型类中声明了一个泛型方法,使用泛型T,注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型
public void show(T t){
System.out.println(t);
}
public T fun(E e){
System.out.println(e);
return key;
}
//泛型的数量也可以为任意多个
public R showKeyName(R r,V v){
return null;
}
/*
* 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法)
* 即使静态方法要使用泛型类中已经声明过的泛型也不可以。
* 如:public static void method(T t){...},此时编译器会提示错误信息:
* Cannot make a static reference to the non-static type T
*/
public static void method(E t){}
}
public class GenericTest {
public static void main(String[] args) {
Generic od = new Generic();
od.show("hello"); //hello
Generic od2 = new Generic();
od2.show(132); //132
}
}
import java.util.ArrayList;
import java.util.Collection;
//通配符
class Animal{}
class Cat extends Animal{}
class Dog extends Animal{}
public class GenericDemo05 {
public static void main(String[] args) {
//? 任意类型
Collection> c1 = new ArrayList();
Collection> c2 = new ArrayList();
Collection> c3 = new ArrayList();
//? extends E (向下限定)
Collection extends Animal> c4 = new ArrayList();
Collection extends Animal> c5 = new ArrayList();
Collection extends Animal> c6 = new ArrayList();
// Collection extends Animal> c4 = new ArrayList
//编译出错
//Erasure of method setList(List) is the same as another method in type GenericDemo
//即:方法setList(List)的擦除与GenericDemo类型中的另一个方法相同
public void setList(List list){}
public void setList(List list){}
import java.util.ArrayList;
public class Q29 {
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add("a");
al.add("b");
accept(al);
}
public static void accept(ArrayList al) {
for (Object o : al)
System.out.println(o);
}
}
List[] ls = new ArrayList[10];//Cannot create a generic array of ArrayList
而使用通配符创建泛型数组是可以的,如下面这个例子:
List>[] ls = new ArrayList>[10];
//这样也是可以的:
List[] ls = new ArrayList[10];
这么做的原因,是为了防止下述代码产生的类型安全问题:
// Not really allowed.
List[] lsa = new List[10]; //1
Object o = lsa;
Object[] oa = (Object[]) o;
List li = new ArrayList();
li.add(new Integer(3));
// Unsound, but passes run time store check
oa[1] = li;
// Run-time error: ClassCastException.
String s = lsa[1].get(0); //2
// OK, array of unbounded wildcard type.
List>[] lsa = new List>[10]; //1
Object o = lsa;
Object[] oa = (Object[]) o;
List li = new ArrayList();
li.add(new Integer(3));
// Correct.
oa[1] = li;
// Run time error, but cast is explicit.
String s = (String) lsa[1].get(0); //2
List[] lsa = (List[])Array.newInstance(ArrayList.class, 4); //1
Object o = lsa;
Object[] oa = (Object[]) o;
List li = new ArrayList();
li.add(new Integer(3));
// Correct.
oa[1] = li;
// Run time error, but cast is explicit.
String s = lsa[1].get(0); //2
@Deprecated
public Date(int year, int month, int date) {
this(year, month, date, 0, 0, 0);
}
@Deprecated
public Date(int year, int month, int date, int hrs, int min) {
this(year, month, date, hrs, min, 0);
}
@Deprecated
public Date(int year, int month, int date, int hrs, int min) {
this(year, month, date, hrs, min, 0);
}
@Deprecated
public int getYear() {
return normalize().getYear() - 1900;
}
...
原文地址:http://www.cnblogs.com/Kavlez/p/4268601.html Enumeration
于Java 1.5增加的enum type...enum type是由一组固定的常量组成的类型,比如四个季节、扑克花色。在出现enum type之前,通常用一组int常量表示枚举类型。比如这样:
public static final int APPLE_FUJI = 0
第二章 Getting Started
1.Hive最大的局限性是什么?一是不支持行级别的增删改(insert, delete, update)二是查询性能非常差(基于Hadoop MapReduce),不适合延迟小的交互式任务三是不支持事务2. Hive MetaStore是干什么的?Hive persists table schemas and other system metadata.
/*
* 0.use a TwoWayLinkedList to store the path.when the node can't be path,you should/can delete it.
* 1.curSum==exceptedSum:if the lastNode is TreeNode,printPath();delete the node otherwise
//js获取项目根路径,如: http://localhost:8083/uimcardprj
function getRootPath(){
//获取当前网址,如: http://localhost:8083/uimcardprj/share/meun.jsp
var curWwwPath=window.document.locati
在Linux下面部 署应用的时候,有时候会遇上Socket/File: Can’t open so many files的问题;这个值也会影响服务器的最大并发数,其实Linux是有文件句柄限制的,而且Linux默认不是很高,一般都是1024,生产服务器用 其实很容易就达到这个数量。下面说的是,如何通过正解配置来改正这个系统默认值。因为这个问题是我配置Nginx+php5时遇到了,所以我将这篇归纳进