2013-06-07 79 views
5

Trong C++, đoạn code sau:Làm thế nào để khởi tạo một biến địa phương trong Java chỉ một lần

#include <stdio.h> 

static const char *init() 
{ 
    printf("in init()\n"); 
} 

static void func() 
{ 
    static const char *str = init(); 
    printf("in func()\n"); 
} 

int main() 
{ 
    for (int i=0; i<10; ++i) { 
     func(); 
    } 
    return 0; 
} 

cho thấy rằng bất chấp vô số các invokations của func(), str chỉ khởi tạo một lúc bằng cách in thông báo dấu vết trong hàm init() được sử dụng để khởi tạo str. Khi chạy, có tổng cộng 10 dòng của dấu vết, một lần cho init() và 10 lần cho func()

Trong Java, không nên đoạn mã sau làm điều tương tự?

class test { 
    private String init() 
    { 
     System.out.println("in init()"); 
     return "FOO"; 
    } 

    private void func() 
    { 
     final String str = init(); 
     System.out.println("in func()"); 
    } 

    public test() 
    { 
     for (int i=0; i<10; ++i) { 
      func(); 
     } 
    } 

    public static main(String[] args) 
    { 
     test app = new test(); 
    } 
} 

Khi chạy, có 20 dòng đầu ra, 10 cho mỗi init()func(). Dựa trên những gì tôi đọc về các biến số cuối cùng, tôi nghĩ rằng nó sẽ hoạt động theo cùng một cách. Vì vậy, tôi đã thử static final và nó sẽ không biên dịch (cũng không chỉ static) Có cách nào để thực hiện việc này không? Tôi cần gọi hàm khởi tạo tốn thời gian từ một số phương thức khác nhau trong lớp của mình, vì vậy, việc di chuyển biến sang phạm vi lớp sẽ không hoạt động. Hơn nữa, vì các biến cục bộ không được tự động khởi tạo, tôi không thể bao gồm một bài kiểm tra nếu cho null xung quanh biến trước khi gán cho nó một giá trị. Tôi cho rằng tôi có thể tạo một biến trong phạm vi lớp cho mỗi phương thức trong lớp học của tôi, nhưng quản lý nó sẽ là một nỗi đau để quản lý. Sự giống nhau tốt nhất sẽ là cái gì nếu tôi được bao gồm một cái gì đó như sau trong mọi phương pháp:

public myfunc1() 
{ 
    final String funcName = java.lang.Thread.currentThread().getStackTrace()[1].getMethodName(); 
} 
public myfunc2() 
{ 
    final String funcName = java.lang.Thread.currentThread().getStackTrace()[1].getMethodName(); 
} 

funcname trong trường hợp này sẽ nhận được một giá trị duy nhất trong mỗi phương pháp, nhưng việc khởi tạo là tốn kém.

+0

Bạn cần boft chuỗi str và hàm init() là tĩnh – maverik

+0

_str_ không thể _static_, nó sẽ không biên dịch. _init() _ không thể _static_ vì nó dựa trên dữ liệu cá thể. – Xaq

+0

http: // ideone.com/nHN6m9 – maverik

Trả lời

1

Vòng loại final làm cho biến không đổi thông qua một cuộc gọi phương thức duy nhất.

Vì bạn muốn có một giá trị cho mỗi trường hợp, bạn có thể sử dụng biến thành viên của cá thể, bên ngoài phương thức.

private final String str = init(); 

private void func() 
{ 
    System.out.println("in func()"); 
} 

Nếu bạn muốn một giá trị duy nhất trên tất cả các phương thức gọi cho tất cả các trường hợp, bạn có thể sử dụng biến thành viên tĩnh, ngoài phương pháp.

private static final String str = init(); 

private void func() 
{ 
    System.out.println("in func()"); 
} 
+0

Không phải là câu hỏi, một cuộc gọi khởi tạo đơn cho mỗi hàm thành viên được gọi nhiều lần. Xem ví dụ ở cuối: _myfunc1() _ và _myfunc2() _ – Xaq

+0

Bạn cũng có thể làm điều đó với các thành viên cá thể - chỉ cần sử dụng một thành viên cá thể khác cho mỗi phương thức trong C bạn sẽ sử dụng biến cục bộ tĩnh. –

+0

Tôi biết rằng, như đã nêu trong câu hỏi, tôi đã tìm kiếm một giải pháp quản lý dễ dàng hơn thay vì tạo một biến cá thể cho mọi phương thức trong lớp của tôi. – Xaq

4

Sau đây là một xấp xỉ khá chặt chẽ:

class test { 

    private static final String str = init(); 

    private static String init() 
    { 
     System.out.println("in init()"); 
     return "FOO"; 
    } 

    private void func() 
    { 
     System.out.println("in func()"); 
    } 

    public test() 
    { 
     for (int i=0; i<10; ++i) { 
      func(); 
     } 
    } 

    public static void main(String[] args) 
    { 
     test app = new test(); 
    } 
} 

Lưu ý rằng str được khởi tạo khi lớp được nạp, không phải khi func() được gọi là cho lần đầu tiên.

+0

Và nếu 'init()' thực sự cần ngữ cảnh, các thành viên không được khởi tạo cho đến khi xây dựng lớp hoặc sau đó, khởi tạo 'str' thành null và có' init() 'chỉ làm điều dài của nó' if (str == null) '. – CPerkins

+0

Thật không may, điều này không cung cấp câu trả lời, đó là lý do tại sao tôi cung cấp các ví dụ khác hoặc _myfunc1() và _myfunc2() _ ở cuối câu hỏi của tôi. – Xaq

Các vấn đề liên quan