Скрытые функции Java

Внутренний класс и вложенный статический класс в Java - это классы, объявленные внутри другого класса, известного как класс верхнего уровня в Java. В терминологии Java. Если вы объявляете вложенный класс static, он будет вызывать вложенный статический класс в Java, а нестатический вложенный класс просто называется Inner Class.

Что такое Inner Class в Java?

Любой класс, который не является верхним уровнем или объявлен внутри другого класса, известен как вложенный класс и из тех вложенных классов, класс, которые объявлены нестатические известны как класс Inner в Java. в Java есть три типа класса Inner:

1) Локальный внутренний класс - объявляется внутри кодового блока или метода. 2) Анонимный внутренний класс - это класс, который не имеет имени для ссылки и инициализируется в том же месте, где он создается. 3) Внутренний класс члена - объявлен как нестационарный член внешнего класса.

public class InnerClassTest {
    public static void main(String args[]) {      
        //creating local inner class inside method i.e. main() 
        class Local {
            public void name() {
                System.out.println("Example of Local class in Java");

            }
        }      
        //creating instance of local inner class
        Local local = new Local();
        local.name(); //calling method from local inner class

        //Creating anonymous inner class in Java for implementing thread
        Thread anonymous = new Thread(){
            @Override
            public void run(){
                System.out.println("Anonymous class example in java");
            }
        };
        anonymous.start();

        //example of creating instance of inner class
        InnerClassTest test = new InnerClassTest();
        InnerClassTest.Inner inner = test.new Inner();
        inner.name(); //calling method of inner class
    }

     //Creating Inner class in Java
    private class Inner{
        public void name(){
            System.out.println("Inner class example in java");
        }
    }
}

Что такое вложенный статический класс в Java?

Вложенный статический класс - это другой класс, который объявлен внутри класса как члена и статично. Вложенный статический класс также объявляется членом внешнего класса и может быть закрытым, открытым или защищенным, как и любой другой член. Одним из основных преимуществ вложенного статического класса над внутренним классом является то, что экземпляр вложенного статического класса не привязан к какому-либо закрывающему экземпляру класса Outer. Вам также не нужен какой-либо экземпляр класса Outer для создания экземпляра вложенного статического класса в Java .

1) Он может получить доступ к статическим членам данных внешнего класса, включая частные. 2) Статический вложенный класс не может получить доступ к нестатистическому (экземпляру) элементу данных или method .

public class NestedStaticExample {
    public static void main(String args[]){  
        StaticNested nested = new StaticNested();
        nested.name();
    }  
    //static nested class in java
    private static class StaticNested{
        public void name(){
            System.out.println("static nested class example in java");
        }
    }
}

Ссылка: Внутренний класс и вложенный Static Class в Java с примером

295
задан 5 revs, 4 users 57% 23 May 2017 в 02:26
поделиться

100 ответов

Власть, которую Вы можете иметь по сборщику "мусора" и как это управляет объектным набором, очень мощна, специально для продолжительных и чувствительных ко времени приложений. Это запускается со слабых, мягких, и фантомных ссылок в java.lang.ref пакете. Смотрите на тех, специально для создания кэшей (существует java.util. WeakHashMap уже). Теперь выройте немного глубже в ReferenceQueue, и Вы начнете иметь еще больше контроля. Наконец захватите документы о самом сборщике "мусора", и Вы будете в состоянии управлять, как часто он работает, размеры различных областей набора и типы используемых алгоритмов (для Java 5 см. http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html ).

7
ответ дан mpresley 23 November 2019 в 01:34
поделиться

JVisualVM от каталога bin в распределении JDK. При контроле и даже профилировании любого JAVA-приложения, даже один Вы не запускались ни с какими специальными параметрами. Только в последних версиях Java 6SE JDK.

7
ответ дан Bill Michell 23 November 2019 в 01:34
поделиться

Можно получить доступ к заключительным локальным переменным и параметрам в блоках инициализации и методах локальных классов. Рассмотрите это:

    final String foo = "42";
    new Thread() {
        public void run() {
             dowhatever(foo);
        }
    }.start();

Немного как закрытие, не так ли?

7
ответ дан 3 revs 23 November 2019 в 01:34
поделиться

Аннотация, Обрабатывающая API от Java 6, смотрит очень перспектива для генерации кода и статической проверки кода.

8
ответ дан pimeja 23 November 2019 в 01:34
поделиться

Что-то, что действительно удивило меня, было пользовательским механизмом сериализации.

, В то время как эти методы частные!! , они" загадочно " названы JVM во время сериализации объекта.

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

Этот способ, которым можно создать собственную сериализацию для создания его больше "безотносительно" (безопасный, быстрый, редкий, легкий и т.д.)

, Это - что-то, что действительно должно рассматривать, должна ли большая информация быть передана через узлы. Механизм сериализации может быть изменен для отправки половины данных. Существуют много раз, когда узкие места не находятся в платформе, а в сумме той отправленной канавки провод, может сохранить Вас тысячи dlls в аппаратных средствах.

Вот статья. http://java.sun.com/developer/technicalArticles/Programming/serialization/

9
ответ дан 2 revs 23 November 2019 в 01:34
поделиться

Как насчет файлов Свойств в Вашем выборе кодировки? Используемый, чтобы быть при загрузке Свойств Вы обеспечили InputStream и load(), метод декодировал его как ISO-8859-1. Вы могли на самом деле хранить файл в некотором другом кодировании, но необходимо было использовать отвратительный взлом как это после загрузки для надлежащего декодирования данных:

String realProp = new String(prop.getBytes("ISO-8859-1"), "UTF-8");

, Но, с JDK 1.6, существует load() метод, который берет Читателя вместо InputStream, что означает, что можно использовать корректное кодирование с начала (существует также store() метод, который берет Писателя). Это походит на довольно грандиозное предприятие мне, но это, кажется, было, крался в JDK без шумихи вообще. Я только наткнулся на него несколько недель назад, и быстрый поиск Google, поднятый всего одно передающее упоминание о нем.

9
ответ дан Alan Moore 23 November 2019 в 01:34
поделиться

"константа" является ключевым словом, но Вы не можете использовать ее.

int const = 1;   // "not a statement"
const int i = 1; // "illegal start of expression"

я предполагаю, что разработчики компилятора думали, что это могло бы использоваться в будущем, и они должны сохранить зарезервированным.

10
ответ дан Michael Myers 23 November 2019 в 01:34
поделиться

Можно создать строковый sprintf-стиль с помощью String.format ().

String w = "world";
String s = String.format("Hello %s %d", w, 3);

можно, конечно, также использовать специальные спецификаторы для изменения вывода.

Больше здесь: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html#syntax

7
ответ дан Sarel Botha 23 November 2019 в 01:34
поделиться

Joshua Bloch, новый Эффективный Java, является хорошим ресурсом.

6
ответ дан warsze 23 November 2019 в 01:34
поделиться

Некоторые приемы потока управления, finally вокруг return оператор:

int getCount() { 
  try { return 1; }
  finally { System.out.println("Bye!"); }
}

правила для определенное присвоение проверит, что последняя переменная всегда присваивается посредством простого анализа потока управления:

final int foo;
if(...)
  foo = 1;
else
  throw new Exception();
foo+1;
6
ответ дан Bruno De Fraine 23 November 2019 в 01:34
поделиться

Функторы довольно прохладны. Они достаточно близки к указателю функции, который все обычно быстры для высказывания, невозможно в Java.

Функторы в Java

4
ответ дан Brad Barker 23 November 2019 в 01:34
поделиться

SwingWorker для того, чтобы легко справиться с обратными вызовами пользовательского интерфейса от фоновых потоков.

4
ответ дан Dan Vinton 23 November 2019 в 01:34
поделиться

Перекрестные типы позволяют, Вы к (своего рода вид) делаете перечисления, которые имеют иерархию наследования. Вы не можете наследовать реализацию, но можно делегировать ее к классу помощника.

enum Foo1 implements Bar {}
enum Foo2 implements Bar {}

class HelperClass {
   static <T extends Enum<T> & Bar> void fooBar(T the enum) {}
}

Это полезно, когда у Вас есть много различных перечислений, которые реализуют своего рода шаблон. Например, много пар перечислений, которые имеют отношения отцов и детей.

enum PrimaryColor {Red, Green, Blue;}
enum PastelColor {Pink, HotPink, Rockmelon, SkyBlue, BabyBlue;}

enum TransportMedium {Land, Sea, Air;}
enum Vehicle {Car, Truck, BigBoat, LittleBoat, JetFighter, HotAirBaloon;}

можно ли записать общие методы, которые говорят "Хорошо, учитывая перечисление значений, это - родитель некоторых других перечислимых значений, какой процент всех возможных дочерних перечислений дочернего типа имеют это конкретное родительское значение как их родителя?", и имейте все это безопасное с точки зрения типов и обошедшееся без кастинг. (например: то "Море" составляет 33% всех возможных механизмов и "Зеленые" 20% всех возможных Пастелей).

код похожи на это. Это довольно противно, но существуют способы сделать его лучше. Обратите внимание в particuar, что сами "листовые" классы довольно аккуратны - универсальные классы имеют объявления, которые ужасно ужасны, но Вы только пишете им onece. После того как универсальные классы там, затем используют их, легко.

import java.util.EnumSet;

import javax.swing.JComponent;

public class zz extends JComponent {

    public static void main(String[] args) {
        System.out.println(PrimaryColor.Green + " " + ParentUtil.pctOf(PrimaryColor.Green) + "%");
        System.out.println(TransportMedium.Air + " " + ParentUtil.pctOf(TransportMedium.Air) + "%");
    }


}

class ParentUtil {
    private ParentUtil(){}
    static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> //
    float pctOf(P parent) {
        return (float) parent.getChildren().size() / //
                (float) EnumSet.allOf(parent.getChildClass()).size() //
                * 100f;
    }
    public static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> //
    EnumSet<C> loadChildrenOf(P p) {
        EnumSet<C> cc = EnumSet.noneOf(p.getChildClass());
        for(C c: EnumSet.allOf(p.getChildClass())) {
            if(c.getParent() == p) {
                cc.add(c);
            }
        }
        return cc;
    }
}

interface Parent<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> {
    Class<C> getChildClass();

    EnumSet<C> getChildren();
}

interface Child<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> {
    Class<P> getParentClass();

    P getParent();
}

enum PrimaryColor implements Parent<PrimaryColor, PastelColor> {
    Red, Green, Blue;

    private EnumSet<PastelColor>    children;

    public Class<PastelColor> getChildClass() {
        return PastelColor.class;
    }

    public EnumSet<PastelColor> getChildren() {
        if(children == null) children=ParentUtil.loadChildrenOf(this);
        return children;
    }
}

enum PastelColor implements Child<PrimaryColor, PastelColor> {
    Pink(PrimaryColor.Red), HotPink(PrimaryColor.Red), //
    Rockmelon(PrimaryColor.Green), //
    SkyBlue(PrimaryColor.Blue), BabyBlue(PrimaryColor.Blue);

    final PrimaryColor  parent;

    private PastelColor(PrimaryColor parent) {
        this.parent = parent;
    }

    public Class<PrimaryColor> getParentClass() {
        return PrimaryColor.class;
    }

    public PrimaryColor getParent() {
        return parent;
    }
}

enum TransportMedium implements Parent<TransportMedium, Vehicle> {
    Land, Sea, Air;

    private EnumSet<Vehicle>    children;

    public Class<Vehicle> getChildClass() {
        return Vehicle.class;
    }

    public EnumSet<Vehicle> getChildren() {
        if(children == null) children=ParentUtil.loadChildrenOf(this);
        return children;
    }
}

enum Vehicle implements Child<TransportMedium, Vehicle> {
    Car(TransportMedium.Land), Truck(TransportMedium.Land), //
    BigBoat(TransportMedium.Sea), LittleBoat(TransportMedium.Sea), //
    JetFighter(TransportMedium.Air), HotAirBaloon(TransportMedium.Air);

    private final TransportMedium   parent;

    private Vehicle(TransportMedium parent) {
        this.parent = parent;
    }

    public Class<TransportMedium> getParentClass() {
        return TransportMedium.class;
    }

    public TransportMedium getParent() {
        return parent;
    }
}
5
ответ дан paulmurray 23 November 2019 в 01:34
поделиться

Плагин Java следующего поколения, найденный в Обновлении Java 1.6 10 и позже, имеет некоторые очень аккуратные функции:

  • Передача java_arguments параметр для передачи аргументов JVM, которая создается. Это позволяет Вам управлять объемом памяти, данным апплету.
  • Создают отдельные загрузчики класса или даже разделяют JVM для каждого апплета.
  • Указывают версию JVM для использования.
  • Установка частичные ядра Java в случаях, где Вам только нужно подмножество полной функциональности библиотек Java.
  • Лучшая поддержка Vista.
  • Поддержка (экспериментальная), чтобы перетащить апплет из браузера и иметь его, продолжает бежать, когда Вы перешли далеко.

Много других вещей, которые документируются здесь: http://jdk6.dev.java.net/plugin2/

[еще 1110] от этого выпуска здесь: http://jdk6.dev.java.net/6u10ea.html

5
ответ дан Sarel Botha 23 November 2019 в 01:34
поделиться

Строка Параметризованная Фабрика классов.

Class.forName( className ).newInstance();

Загрузка ресурс (файл свойств, xml, xslt, отображают и т.д.) из файла .

this.getClass().getClassLoader().getResourceAsStream( ... ) ;
банки развертывания
5
ответ дан Martin Spamer 23 November 2019 в 01:34
поделиться

Экземпляры того же класса могут получить доступ к членам парламента, не занимающим официального поста других экземпляров:

class Thing {
  private int x;

  public int addThings(Thing t2) {
    return this.x + t2.x;  // Can access t2's private value!
  }
}
6
ответ дан David Koelle 23 November 2019 в 01:34
поделиться

Прочитайте «Пазлы Явы» Джошуа Блоха, и вы будете как просветлены, так и в ужасе.

5
ответ дан 23 November 2019 в 01:34
поделиться

URL-адреса исходного кода. Например, вот некоторый законный исходный код Java:

http://google.com

(Да, это было в Java Puzzlers. Я засмеялся ...)

6
ответ дан 23 November 2019 в 01:34
поделиться

Люди иногда немного удивляются, когда понимают, что это возможно вызвать частные методы и получить доступ / изменить частные поля с помощью отражения ...

Рассмотрим следующий класс:

public class Foo {
    private int bar;

    public Foo() {
        setBar(17);
    }

    private void setBar(int bar) {
        this.bar=bar;
    }

    public int getBar() {
        return bar;
    }

    public String toString() {
        return "Foo[bar="+bar+"]";
    }
}

Выполнение этой программы ...

import java.lang.reflect.*;

public class AccessibleExample {
    public static void main(String[] args)
        throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, NoSuchFieldException {
        Foo foo=new Foo();
        System.out.println(foo);

        Method method=Foo.class.getDeclaredMethod("setBar", int.class);
        method.setAccessible(true);
        method.invoke(foo, 42);

        System.out.println(foo);
        Field field=Foo.class.getDeclaredField("bar");
        field.setAccessible(true);
        field.set(foo, 23);
        System.out.println(foo);
    }
}

... даст следующий результат:

Foo[bar=17]
Foo[bar=42]
Foo[bar=23]
8
ответ дан 23 November 2019 в 01:34
поделиться

Уловка оптимизации, которая упрощает поддержку кода и снижает уязвимость к ошибкам параллелизма.

public class Slow {
  /** Loop counter; initialized to 0. */
  private long i;

  public static void main( String args[] ) {
    Slow slow = new Slow();

    slow.run();
  }

  private void run() {
    while( i++ < 10000000000L )
      ;
  }
}

$ time java Slow
реальный 0 мин. 15,397 с
$ time java Slow
реальный 0m20.012s
$ time java Slow
реальный 0 мин. 18,645 с

Среднее значение: 18,018 с

public class Fast {
  /** Loop counter; initialized to 0. */
  private long i;

  public static void main( String args[] ) {
    Fast fast = new Fast();

    fast.run();
  }

  private void run() {
    long i = getI();

    while( i++ < 10000000000L )
      ;

    setI( i );
  }

  private long setI( long i ) {
    this.i = i;
  }

  private long getI() {
    return this.i;
  }
}

$ time java Быстро
реальный 0 мин. 12,003 с
$ time java Fast
реальный 0 мин. 9,840 с
$ time java Fast
real 0m9.686s

Среднее значение: 10.509s

Для ссылки на переменную области класса требуется больше байт-кодов, чем на переменную области действия метода. Добавление вызова метода перед критическим циклом добавляет небольшие накладные расходы (и вызов может быть встроен компилятором в любом случае).

Еще одно преимущество этого метода (всегда использующего аксессоры) состоит в том, что он устраняет потенциальную ошибку в Медленный класс. Если бы второй поток постоянно сбрасывал значение i на 0 (например, путем вызова slow.setI (0) ), класс Slow мог никогда не заканчивать цикл. Вызов метода доступа и использование локальной переменной исключает эту возможность.

Протестировано с использованием J2SE 1.6.0_13 в Linux 2.6.27-14.

10
ответ дан 23 November 2019 в 01:34
поделиться

Уже упоминалось , что конечный массив может использоваться для передачи переменной из анонимных внутренних классов.

Другой, возможно лучший и менее уродливый подход - использовать AtomicReference ( или AtomicBoolean / AtomicInteger /…) из пакета java.util.concurrent.atomic.

Одним из преимуществ этого является то, что эти классы также предоставляют такие методы, как compareAndSet , которые могут быть полезны, если вы создаете несколько потоков, которые могут изменять одну и ту же переменную.


Еще один полезный связанный шаблон:

final AtomicBoolean dataMsgReceived = new AtomicBoolean(false);
final AtomicReference<Message> message = new AtomicReference<Message>();
withMessageHandler(new MessageHandler() {
    public void handleMessage(Message msg) {
         if (msg.isData()) {
             synchronized (dataMsgReceived) {
                 message.set(msg);
                 dataMsgReceived.set(true);
                 dataMsgReceived.notifyAll();
             }
         }
    }
}, new Interruptible() {
    public void run() throws InterruptedException {
        synchronized (dataMsgReceived) {
            while (!dataMsgReceived.get()) {
                dataMsgReceived.wait();
            }
        }
    }
});

В этом конкретном примере мы могли бы просто подождать, пока сообщение не станет ненулевым, однако null часто может быть допустимым значением, и тогда вам нужно использовать отдельный флаг для завершения ожидания.

waitMessageHandler (… ) выше - еще один полезный шаблон: он где-то устанавливает обработчик, затем начинает выполнение Interruptible , которое может вызвать исключение, а затем удаляет обработчик в блоке finally, например:

private final AtomicReference<MessageHandler> messageHandler = new AtomicReference<MessageHandler>();
public void withMessageHandler(MessageHandler handler, Interruptible logic) throws InterruptedException {
    synchronized (messageHandler) {
        try {
            messageHandler.set(handler);
            logic.run();
        } finally {
            messageHandler.set(null);
        }
    }
}

] Здесь я предполагаю, что метод messageHandler (если он не равен нулю) handleMessage (…) вызывается другим потоком при получении сообщения. messageHandler не должен быть просто типа MessageHandler : таким образом вы будете синхронизировать изменяющуюся переменную, что явно является ошибкой.

Конечно, это не так.

5
ответ дан 23 November 2019 в 01:34
поделиться

Большинство людей не знают, что могут клонировать массив.

int[] arr = {1, 2, 3};
int[] arr2 = arr.clone();
8
ответ дан 23 November 2019 в 01:34
поделиться

Запятая и массив. Это допустимый синтаксис: String s [] = {
«123»,
«234» ,
};

5
ответ дан 23 November 2019 в 01:34
поделиться

Use StringBuilder instead of StringBuffer when you don't need synchronized management included in StringBuilder. It will increase the performance of your application.

Improvements for Java 7 would be even better than any hidden Java features:

  • Diamond syntax: Link

Don't use those infinite <> syntax at instanciation:

Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

// Can now be replaced with this:

Map<String, List<String>> anagrams = new HashMap<>();
  • Strings in switch: Link

Use String in switch, instead of old-C int:

String s = "something";
switch(s) {
 case "quux":
    processQuux(s);
    // fall-through

  case "foo":
  case "bar":
    processFooOrBar(s);
    break;

  case "baz":
     processBaz(s);
    // fall-through

  default:
    processDefault(s);
    break;
}
  • Automatic Resource Management Link

This old code:

static void copy(String src, String dest) throws IOException {
    InputStream in = new FileInputStream(src);
    try {
        OutputStream out = new FileOutputStream(dest);
        try {
            byte[] buf = new byte[8 * 1024];
            int n;
            while ((n = in.read(buf)) >= 0)
                out.write(buf, 0, n);
        } finally {
            out.close();
        }
    } finally {
        in.close();
    }
}

can now be replaced by this much simpler code:

static void copy(String src, String dest) throws IOException {
    try (InputStream in = new FileInputStream(src);
            OutputStream out = new FileOutputStream(dest)) {
        byte[] buf = new byte[8192];
        int n;
        while ((n = in.read(buf)) >= 0)
            out.write(buf, 0, n);
    }
}
10
ответ дан 23 November 2019 в 01:34
поделиться

На самом деле, что мне нравится в Java, так это то, как мало там скрытых уловок. Это очень очевидный язык. Настолько, что через 15 лет почти все, о которых я могу думать, уже перечислены на этих нескольких страницах.

Возможно, большинство людей знает, что Collections.synchronizedList () добавляет синхронизацию в список. Чего вы не можете знать, если не прочитаете документацию, так это того, что вы можете безопасно выполнять итерацию по элементам этого списка, синхронизируя сам объект списка.

CopyOnWriteArrayList может быть неизвестен некоторым,

7
ответ дан 23 November 2019 в 01:34
поделиться

Идентификаторы могут содержать иностранные языковые символы, такие как умлауты:

вместо написания:

String title="";

Кто-то мог написать:

String Überschrift="";
9
ответ дан 23 November 2019 в 01:34
поделиться

Не читал об этом

Integer a = 1;
Integer b = 1;
Integer c = new Integer(1);
Integer d = new Integer(1);

Integer e = 128;
Integer f = 128;

assertTrue (a == b);   // again: this is true!
assertFalse(e == f); // again: this is false!
assertFalse(c == d);   // again: this is false!

Подробнее об этом, поисшив Java Pool of Integer (внутренний кэш-кеш »от -128 до 127 для AutoBoxing) или посмотреть в Integer.Valueof

6
ответ дан 23 November 2019 в 01:34
поделиться

Java 6 (от Sun) поставляется с встроенным переводчиком Javascrip.

http://java.sun.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html#sjsengine

5
ответ дан 23 November 2019 в 01:34
поделиться

Я могу добавить объект Scanner. Он лучше всего подходит для парсинга.

String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();
9
ответ дан 23 November 2019 в 01:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: