JAVA中关于Object的问题.麻烦进来看看.谢谢!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA中关于Object的问题.麻烦进来看看.谢谢!相关的知识,希望对你有一定的参考价值。

class Demo

private int num;

Demo(int num)

this.num = num;

public boolean equals(Object obj)

Demo d = (Demo)obj;
return this.num == d.num;



class ObjectDemo2

public static void main(String[] args)

Demo d1 = new Demo(5);
Demo d2 = new Demo(5);
boolean b = d1.equals(d2);
System.out.println("b="+b);



1,视频上说在第11行,也就是Demo d = (Demo)obj;这句必须要这样强制转换,否则会报错,因为Object没有定义num属性,而原先在第9行这句是,boolean compare(Demo d)则不需要强制转换.我就纳闷儿了,为什么Object没有定义num属性,而Demo却定义了呢?

2,在11行Demo d = (Demo)obj;这句中 (Demo)为什么要用括弧框起来?括弧这里是什么意思?括弧在这里有什么特殊含义?这个括弧我是完全没搞明白啊!

3,望大家伙帮帮忙啊.谢谢了!

1.实际上所有类都继承自Object类,public boolean equals(Object obj)这个方法是Demo类覆盖Object的同名方法,你当然不能改变方法参数的类型,Demo类继承了Object所有的属性和方法,num属性是Demo自己的扩展属性
2。在11行Demo d = (Demo)obj;这句中 (Demo)要用括弧框起来是强制类型转换,
如int i=(int)7.5f,
因为是向下类型转换,实际上是类型取值范围缩小,强制把Object对象转换为Demo对象,要用括弧框起来,这是标准操作
参考技术A 如果写成这样Demoobj那它就变意思了…… (Demo)obj 这是强制转换的固定语法形势 特别是括弧里是 自定义的 “类”类型的

安卓开发(Java)中关于final关键字与线程安全性

前言

学习新知识固然重要,但是时常往回看看,温故知新是很必要的。回顾一下线程安全性和final关键字。

正文

从Java 5开始,final keyword一个特殊用法是在并发库中一个非常重要且经常被忽视的武器。实质上,可以使用final来确保在构造对象时,访问该对象的另一个线程不会看到处于部分构造状态的对象,否则可能会发生这种情况。这是因为当作为对象变量的一个属性时,final作为其定义的一部分具有以下重要特征:

当构造函数退出时,final keyword的值保证对访问构造对象的其他线程可见。

使用final是所谓的安全发布(safe publication)的一种方式,这里,发布(publication)一个地相意味着在一个线程中创建它,同时另一个线程在之后的某时刻可以引用到该新创建的对象。当JVM调用对象的构造函数时,它必须将各成员赋值,同时存储一个指向该对象的指针。就像其他任何的数据写入一样,这可能是乱序的,and their application to main memory can be delayed and other processors can be delayed unless you take special steps to combat this(看不太懂,是不是说“把他们写回主存可能推迟,并且其他的处理器(看到变化)也会推迟,要客服这一点,除非采取非常步骤”)。特别的,指向对象的引用可能在成员变量提交之前(导致如此的原因之一是编译器的指令重排ordering:if you think about how you‘d write things in a low-level language such as C or assembler, it‘s quite natural to store a pointer to a block of memory, and then advance the pointer as you‘re writing data to that block)就被写入到主存并被访问到了。这样会导致另一个线程看到了一个不合法或不完整的对象。

而final可以防止此类事情的发生:如果某个成员是final的,JVM规范做出如下明确的保证:一旦对象引用对其他线程可见,则其final成员也必须正确的赋值了。

final的对象引用

对象的final成员成员的值在当退出构造函数时,他们也是最新的。这意味着:

final类型的成员变量的值,包括那些用final引用指向的collections的对象,是读线程安全而无需使用synchronization的

注意,如果你有一个指向collection,数组或其他可变对象的final引用,如果存在其他线程访问,仍然需要使用同步机制来访问该对象(或使用ConcurrentHashMap)。

因此,不可变对象(指所有的成员都是final并且成员要么是基本类型,要么指向另一个不可变对象)可以并发访问而无需使用同步机制。通过final引用读取“实际不可变”对象(指成员虽然实际并不是final,然而却从不会改变)也是安全的。然而,从程序设计的角度来看,在此种情况下强化不可变性是明智的(如用Collections.unmodifiableList()封装一个collection)。That way, you‘ll spot bugs introduced when one of your colleagues naughtily attempts to modify a collection that you didn‘t intend to be modified!

使用final的限制条件和局限性

当声明一个final成员时,必须在构造函数退出前设置它的值,如下:

public class MyClass {

    private final int myField = 3;

    public MyClass() { ... }

}

或者

public class MyClass {

    private final int myField;

    public MyClass() {

        ...

        myField = 3;

        ...

    }

}

需要强调的是将指向对象的成员声明为final只能将该引用设为不可变的,而非所指的对象。例如如果一个list声明如下:

private final List myList =new ArrayList();

仍然可以修改该list

myList.add("Hello");

然而,声明为final可以保证如下操作不合法:

myList =new ArrayList();

myList= someOtherList;

什么时候应该使用final

一个答案就是“尽可能的使用”。任何你不希望改变的(基本类型,或者指向一个对象,不管该对象是否可变)一般来讲都应该声明为final。另一种看待此问题的方式是:

如果一个对象将会在多个线程中访问并且你并没有将其成员声明为final,则必须提供其他方式保证线程安全

“其他方式”可以包括声明成员为volatile,使用synchronized或者显式Lock控制所有该成员的访问。

大家往往忽视的典型case是在一个线程创建一个对象,而后在另一个线程使用,如一个通过ThreadPoolExecutor的对象。这种情况下,必须保证该对象的线程安全性:这和线程的并发访问关系不大,主要是因为在其生命周期内,不同的线程会在任意时刻访问它(还是内存模型的问题吧)



作者:AirrWang
链接:https://www.jianshu.com/p/ba764ca54262
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。





以上是关于JAVA中关于Object的问题.麻烦进来看看.谢谢!的主要内容,如果未能解决你的问题,请参考以下文章

JSONKit中关于‘isa’错误的解决办法

网页制作方面的高手进来看看 `...

java中关于null的一些理解

Matlab中关于函数bwlabel(I_bw,8)和函数bwboundaries(I_bw,'noholes')问题 高手进来帮忙看看吧 谢谢了

JAVA中关于set()和get()方法的理解及使用

安卓开发(Java)中关于final关键字与线程安全性