" Serializable"中的字段class应该是瞬态的或可序列化的

时间:2018-04-03 14:15:02

标签: java sonarlint

嗨我在声纳lint中收到此错误:

" Serializable"中的字段阶级应该是暂时的或  可序列化

  1. private final条件notEmpty = lock.newCondition();
  2. private final Condition notFull = lock.newCondition();
  3. 私人比较器比较器;
  4. 我的代码是:

    package com.cgi.atom.common.priorityexec;
    
    /**
     * Created by nageswararao.vesepog on 8/24/2016.
     */
    
    import java.util.*;
    import java.util.concurrent.BlockingDeque;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class PriorityBlockingDeque<E>
            extends AbstractQueue<E>
            implements BlockingDeque<E>, java.io.Serializable {
    
        /*
         * Implemented as a navigable set protected by a
         * single lock and using conditions to manage blocking.
         */
    
        private final int capacity;
    
        private final LinkedList<E> list;
        /**
         * Main lock guarding all access
         */
        private final ReentrantLock lock = new ReentrantLock();
        /**
         * Condition for waiting takes
         */
        private final Condition  notEmpty = lock.newCondition();
        /**
         * Condition for waiting puts
         */
        private final Condition notFull = lock.newCondition();
        private  Comparator<E> comparator;
    
        /**
         * Creates a <tt>PriorityBlockingDeque</tt> with a capacity of
         * {@link Integer#MAX_VALUE}.
         */
        public PriorityBlockingDeque() {
            this(null, Integer.MAX_VALUE);
        }
    
        /**
         * Creates a <tt>PriorityBlockingDeque</tt> with the given (fixed) capacity.
         *
         * @param capacity the capacity of this deque
         * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
         */
        public PriorityBlockingDeque(int capacity) {
            this(null, capacity);
        }
    
        public PriorityBlockingDeque(Comparator<E> comparator, int capacity) {
            if (capacity <= 0) throw new IllegalArgumentException();
            this.capacity = capacity;
            this.list = new LinkedList<E>();
            this.comparator = comparator;
        }
    
        // Basic adding and removing operations, called only while holding lock
    
        /**
         * Adds e or returns false if full.
         *
         * @param e The element to add.
         * @return Whether adding was successful.
         */
        private boolean innerAdd(E e) {
            if (list.size() >= capacity)
                return false;
    
            int insertionPoint = Collections.binarySearch(list, e, comparator);
            if (insertionPoint < 0) {
                // this means the key didn't exist, so the insertion point is negative minus 1.
                insertionPoint = -insertionPoint - 1;
            }
    
            list.add(insertionPoint, e);
            notEmpty.signal();
    
            return true;
        }
    
        /**
         * Removes and returns first element, or null if empty.
         *
         * @return The removed element.
         */
        private E innerRemoveFirst() {
            E f = list.pollFirst();
            if (f == null)
                return null;
    
    
            notFull.signal();
            return f;
        }
    
        /**
         * Removes and returns last element, or null if empty.
         *
         * @return The removed element.
         */
        private E innerRemoveLast() {
            E l = list.pollLast();
            if (l == null)
                return null;
    
            notFull.signal();
            return l;
        }
    
        // BlockingDeque methods
    
        /**
         * @throws IllegalStateException {@inheritDoc}
         * @throws NullPointerException  {@inheritDoc}
         */
        public void addFirst(E e) {
            if (!offerFirst(e))
                throw new IllegalStateException("Deque full");
        }
    
        /**
         * @throws IllegalStateException {@inheritDoc}
         * @throws NullPointerException  {@inheritDoc}
         */
        public void addLast(E e) {
            if (!offerLast(e))
                throw new IllegalStateException("Deque full");
        }
    
        /**
         * @throws NullPointerException {@inheritDoc}
         */
        public boolean offerFirst(E e) {
            if (e == null) throw new NullPointerException();
            lock.lock();
            try {
                return innerAdd(e);
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * @throws NullPointerException {@inheritDoc}
         */
        public boolean offerLast(E e) {
            if (e == null) throw new NullPointerException();
            lock.lock();
            try {
                return innerAdd(e);
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * @throws NullPointerException {@inheritDoc}
         * @throws InterruptedException {@inheritDoc}
         */
        public void putFirst(E e) throws InterruptedException {
            if (e == null) throw new NullPointerException();
            lock.lock();
            try {
                while (!innerAdd(e))
                    notFull.await();
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * @throws NullPointerException {@inheritDoc}
         * @throws InterruptedException {@inheritDoc}
         */
        public void putLast(E e) throws InterruptedException {
            if (e == null) throw new NullPointerException();
            lock.lock();
            try {
                while (!innerAdd(e))
                    notFull.await();
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * @throws NullPointerException {@inheritDoc}
         * @throws InterruptedException {@inheritDoc}
         */
        public boolean offerFirst(E e, long timeout, TimeUnit unit)
                throws InterruptedException {
            if (e == null) throw new NullPointerException();
            long nanos = unit.toNanos(timeout);
            lock.lockInterruptibly();
            try {
                for (; ;) {
                    if (innerAdd(e))
                        return true;
                    if (nanos <= 0)
                        return false;
                    nanos = notFull.awaitNanos(nanos);
                }
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * @throws NullPointerException {@inheritDoc}
         * @throws InterruptedException {@inheritDoc}
         */
        public boolean offerLast(E e, long timeout, TimeUnit unit)
                throws InterruptedException {
            if (e == null) throw new NullPointerException();
            long nanos = unit.toNanos(timeout);
            lock.lockInterruptibly();
            try {
                for (; ;) {
                    if (innerAdd(e))
                        return true;
                    if (nanos <= 0)
                        return false;
                    nanos = notFull.awaitNanos(nanos);
                }
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * @throws NoSuchElementException {@inheritDoc}
         */
        public E removeFirst() {
            E x = pollFirst();
            if (x == null) throw new NoSuchElementException();
            return x;
        }
    
        /**
         * @throws NoSuchElementException {@inheritDoc}
         */
        public E removeLast() {
            E x = pollLast();
            if (x == null) throw new NoSuchElementException();
            return x;
        }
    
        public E pollFirst() {
            lock.lock();
            try {
                return innerRemoveFirst();
            } finally {
                lock.unlock();
            }
        }
    
        public E pollLast() {
            lock.lock();
            try {
                return innerRemoveLast();
            } finally {
                lock.unlock();
            }
        }
    
        public E takeFirst() throws InterruptedException {
            lock.lock();
            try {
                E x;
                while ((x = innerRemoveFirst()) == null)
                    notEmpty.await();
                return x;
            } finally {
                lock.unlock();
            }
        }
    
        public E takeLast() throws InterruptedException {
            lock.lock();
            try {
                E x;
                while ((x = innerRemoveLast()) == null)
                    notEmpty.await();
                return x;
            } finally {
                lock.unlock();
            }
        }
    
        public E pollFirst(long timeout, TimeUnit unit)
                throws InterruptedException {
            long nanos = unit.toNanos(timeout);
            lock.lockInterruptibly();
            try {
                for (; ;) {
                    E x = innerRemoveFirst();
                    if (x != null)
                        return x;
                    if (nanos <= 0)
                        return null;
                    nanos = notEmpty.awaitNanos(nanos);
                }
            } finally {
                lock.unlock();
            }
        }
    
        public E pollLast(long timeout, TimeUnit unit)
                throws InterruptedException {
            long nanos = unit.toNanos(timeout);
            lock.lockInterruptibly();
            try {
                for (; ;) {
                    E x = innerRemoveLast();
                    if (x != null)
                        return x;
                    if (nanos <= 0)
                        return null;
                    nanos = notEmpty.awaitNanos(nanos);
                }
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * @throws NoSuchElementException {@inheritDoc}
         */
        public E getFirst() {
            E x = peekFirst();
            if (x == null) throw new NoSuchElementException();
            return x;
        }
    
        /**
         * @throws NoSuchElementException {@inheritDoc}
         */
        public E getLast() {
            E x = peekLast();
            if (x == null) throw new NoSuchElementException();
            return x;
        }
    
        public E peekFirst() {
            lock.lock();
            try {
                return list.size() == 0 ? null : list.peekFirst();
            } finally {
                lock.unlock();
            }
        }
    
        public E peekLast() {
            lock.lock();
            try {
                return list.size() == 0 ? null : list.peekLast();
            } finally {
                lock.unlock();
            }
        }
    
        public boolean removeFirstOccurrence(Object o) {
            if (o == null) return false;
            lock.lock();
            try {
                for (Iterator<E> it = list.iterator(); it.hasNext();) {
                    E e = it.next();
                    if (o.equals(e)) {
                        it.remove();
                        return true;
                    }
                }
                return false;
            } finally {
                lock.unlock();
            }
        }
    
        public boolean removeLastOccurrence(Object o) {
            if (o == null) return false;
            lock.lock();
            try {
                for (Iterator<E> it = list.descendingIterator(); it.hasNext();) {
                    E e = it.next();
                    if (o.equals(e)) {
                        it.remove();
                        return true;
                    }
                }
                return false;
            } finally {
                lock.unlock();
            }
        }
    
        // BlockingQueue methods
    
        /**
         * Inserts the specified element to the deque unless it would
         * violate capacity restrictions.  When using a capacity-restricted deque,
         * it is generally preferable to use method {@link #offer(Object) offer}.
         * <p/>
         * <p>This method is equivalent to {@link #addLast}.
         *
         * @throws IllegalStateException if the element cannot be added at this
         *                               time due to capacity restrictions
         * @throws NullPointerException  if the specified element is null
         */
        @Override
        public boolean add(E e) {
            addLast(e);
            return true;
        }
    
        /**
         * @throws NullPointerException if the specified element is null
         */
        public boolean offer(E e) {
            return offerLast(e);
        }
    
        /**
         * @throws NullPointerException {@inheritDoc}
         * @throws InterruptedException {@inheritDoc}
         */
        public void put(E e) throws InterruptedException {
            putLast(e);
        }
    
        /**
         * @throws NullPointerException {@inheritDoc}
         * @throws InterruptedException {@inheritDoc}
         */
        public boolean offer(E e, long timeout, TimeUnit unit)
                throws InterruptedException {
            return offerLast(e, timeout, unit);
        }
    
        /**
         * Retrieves and removes the head of the queue represented by this deque.
         * This method differs from {@link #poll poll} only in that it throws an
         * exception if this deque is empty.
         * <p/>
         * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
         *
         * @return the head of the queue represented by this deque
         * @throws NoSuchElementException if this deque is empty
         */
        @Override
        public E remove() {
            return removeFirst();
        }
    
        public E poll() {
            return pollFirst();
        }
    
        public E take() throws InterruptedException {
            return takeFirst();
        }
    
        public E poll(long timeout, TimeUnit unit) throws InterruptedException {
            return pollFirst(timeout, unit);
        }
    
        /**
         * Retrieves, but does not remove, the head of the queue represented by
         * this deque.  This method differs from {@link #peek peek} only in that
         * it throws an exception if this deque is empty.
         * <p/>
         * <p>This method is equivalent to {@link #getFirst() getFirst}.
         *
         * @return the head of the queue represented by this deque
         * @throws NoSuchElementException if this deque is empty
         */
        @Override
        public E element() {
            return getFirst();
        }
    
        public E peek() {
            return peekFirst();
        }
    
        /**
         * Returns the number of additional elements that this deque can ideally
         * (in the absence of memory or resource constraints) accept without
         * blocking. This is always equal to the initial capacity of this deque
         * less the current <tt>size</tt> of this deque.
         * <p/>
         * <p>Note that you <em>cannot</em> always tell if an attempt to insert
         * an element will succeed by inspecting <tt>remainingCapacity</tt>
         * because it may be the case that another thread is about to
         * insert or remove an element.
         */
        public int remainingCapacity() {
            lock.lock();
            try {
                return capacity - list.size();
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * @throws UnsupportedOperationException {@inheritDoc}
         * @throws ClassCastException            {@inheritDoc}
         * @throws NullPointerException          {@inheritDoc}
         * @throws IllegalArgumentException      {@inheritDoc}
         */
        public int drainTo(Collection<? super E> c) {
            if (c==null)
                throw new NullPointerException();
            if (c.equals(this))
                throw new IllegalArgumentException();
            lock.lock();
            try {
                for (E e : list) {
                    c.add(e);
                }
                int n = list.size();
                list.clear();
                notFull.signalAll();
                return n;
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * @throws UnsupportedOperationException {@inheritDoc}
         * @throws ClassCastException            {@inheritDoc}
         * @throws NullPointerException          {@inheritDoc}
         * @throws IllegalArgumentException      {@inheritDoc}
         */
        public int drainTo(Collection<? super E> c, int maxElements) {
            if (c ==null)
                throw new NullPointerException();
            if (c.equals(this))
                throw new IllegalArgumentException();
            lock.lock();
            try {
                int n = 0;
                for (Iterator<E> it = list.iterator(); n < maxElements && it.hasNext();) {
                    E e = it.next();
                    c.add(e);
                    it.remove();
                    ++n;
                }
    
                notFull.signalAll();
                return n;
            } finally {
                lock.unlock();
            }
        }
    
        // Stack methods
    
        /**
         * @throws IllegalStateException {@inheritDoc}
         * @throws NullPointerException  {@inheritDoc}
         */
        public void push(E e) {
            addFirst(e);
        }
    
        /**
         * @throws NoSuchElementException {@inheritDoc}
         */
        public E pop() {
            return removeFirst();
        }
    
        // Collection methods
    
        /**
         * Removes the first occurrence of the specified element from this deque.
         * If the deque does not contain the element, it is unchanged.
         * More formally, removes the first element <tt>e</tt> such that
         * <tt>o.equals(e)</tt> (if such an element exists).
         * Returns <tt>true</tt> if this deque contained the specified element
         * (or equivalently, if this deque changed as a result of the call).
         * <p/>
         * <p>This method is equivalent to
         * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
         *
         * @param o element to be removed from this deque, if present
         * @return <tt>true</tt> if this deque changed as a result of the call
         */
        @Override
        public boolean remove(Object o) {
            return removeFirstOccurrence(o);
        }
    
        /**
         * Returns the number of elements in this deque.
         *
         * @return the number of elements in this deque
         */
        @Override
        public int size() {
            lock.lock();
            try {
                return list.size();
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * Returns <tt>true</tt> if this deque contains the specified element.
         * More formally, returns <tt>true</tt> if and only if this deque contains
         * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
         *
         * @param o object to be checked for containment in this deque
         * @return <tt>true</tt> if this deque contains the specified element
         */
        @Override
        public boolean contains(Object o) {
            if (o == null) return false;
            lock.lock();
            try {
                return list.contains(o);
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * Returns an array containing all of the elements in this deque, in
         * proper sequence (from first to last element).
         * <p/>
         * <p>The returned array will be "safe" in that no references to it are
         * maintained by this deque.  (In other words, this method must allocate
         * a new array).  The caller is thus free to modify the returned array.
         * <p/>
         * <p>This method acts as bridge between array-based and collection-based
         * APIs.
         *
         * @return an array containing all of the elements in this deque
         */
        @Override
        public Object[] toArray() {
            lock.lock();
            try {
                return list.toArray();
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * Returns an array containing all of the elements in this deque, in
         * proper sequence; the runtime type of the returned array is that of
         * the specified array.  If the deque fits in the specified array, it
         * is returned therein.  Otherwise, a new array is allocated with the
         * runtime type of the specified array and the size of this deque.
         * <p/>
         * <p>If this deque fits in the specified array with room to spare
         * (i.e., the array has more elements than this deque), the element in
         * the array immediately following the end of the deque is set to
         * <tt>null</tt>.
         * <p/>
         * <p>Like the {@link #toArray()} method, this method acts as bridge between
         * array-based and collection-based APIs.  Further, this method allows
         * precise control over the runtime type of the output array, and may,
         * under certain circumstances, be used to save allocation costs.
         * <p/>
         * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
         * The following code can be used to dump the deque into a newly
         * allocated array of <tt>String</tt>:
         * <p/>
         * <pre>
         *     String[] y = x.toArray(new String[0]);</pre>
         * <p/>
         * Note that <tt>toArray(new Object[0])</tt> is identical in function to
         * <tt>toArray()</tt>.
         *
         * @param a the array into which the elements of the deque are to
         *          be stored, if it is big enough; otherwise, a new array of the
         *          same runtime type is allocated for this purpose
         * @return an array containing all of the elements in this deque
         * @throws ArrayStoreException  if the runtime type of the specified array
         *                              is not a supertype of the runtime type of every element in
         *                              this deque
         * @throws NullPointerException if the specified array is null
         */
        @Override
        public <T> T[] toArray(T[] a) {
            lock.lock();
            try {
                return list.toArray(a);
            } finally {
                lock.unlock();
            }
        }
    
        @Override
        public String toString() {
            lock.lock();
            try {
                return super.toString();
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * Atomically removes all of the elements from this deque.
         * The deque will be empty after this call returns.
         */
        @Override
        public void clear() {
            lock.lock();
            try {
                list.clear();
                notFull.signalAll();
            } finally {
                lock.unlock();
            }
        }
    
        @Override
        public Iterator<E> iterator() {
            return list.iterator();
        }
    
        public Iterator<E> descendingIterator() {
            return list.descendingIterator();
        }
    }
    

    有人可以提供解决方案,以便声纳不会显示所有三个变量的这些错误吗?

2 个答案:

答案 0 :(得分:1)

Sonar 已经给你两个解决方案。

  1. 使它们可序列化
  2. 让它们变得短暂
  3. 你不能做前者,因为他们不是你写过的课程,所以你需要让它们成为瞬态。请参阅:What does the keyword "transient" mean in Java?

    或者,如果您不需要序列化任何PriorityBlockingDeque,那么只需删除该界面即可。

    这是一个警告的原因是因为如何序列化包含不可序列化组件的类?

答案 1 :(得分:0)

Serializable类中的字段本身必须是Serializable或transient,即使该类从未显式序列化或反序列化。例如,在负载下,大多数J2EE应用程序框架将对象刷新到磁盘,而具有非瞬态,非可序列化数据成员的涉嫌Serializable对象可能导致程序崩溃,并为攻击者打开大门。通常,Serializable类应该履行其合同,并且在序列化实例时不会出现意外行为。

此规则在非Serializable字段和集合字段上引发了一个问题,当它们不是私有时(因为它们可以在外部分配非Serializable值),以及在类中分配非Serializable类型时。< / p>

不符合规范的代码示例

public class Address {
  //...
}

public class Person implements Serializable {
 private static final long serialVersionUID = 1905122041950251207L;

 private String name;
 private Address address;  // Noncompliant; Address isn't serializable
}

<强>例外

使所有成员可序列化或瞬态化的替代方法是实现特殊方法,这些方法负责正确地序列化和反序列化对象。此规则忽略实现以下方法的类:

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;

参考:&#34; Serializable&#34;中的字段class应该是瞬态的或可序列化的(squid:S1948)